10

I made an alias ff and sourced it from ~/.zsh/aliases.zsh.

The aliases run well themselves:

alias ff
ff='firefox --safe-mode'

and it runs as expected.

But when I try to run it under gdb I get:

> gdb ff
GNU gdb (Debian 7.12-6+b1) 7.12.0.20161007-git
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
...
For help, type "help".
Type "apropos word" to search for commands related to "word"...
ff: No such file or directory.
(gdb) quit

I tried using gdb firefox --safe-mode but that wouldn't run.

Can somebody identify what is wrong?

3
  • Maybe use gdb zsh -c ff instead.
    – user232326
    Commented Feb 8, 2018 at 0:07
  • 5
    gdb isn’t a shell
    – Jeff Schaller
    Commented Feb 8, 2018 at 0:09
  • Oh, looks like I copied the wrong URL there. Should have been Why does sudo ignore aliases?
    – muru
    Commented Feb 8, 2018 at 5:17

4 Answers 4

20

Aliases are a feature of the shell. Defining an alias creates a new shell command name. It's recognized only by the shell, and only when it appears as a command name.

For example, if you type

> ff

at a shell prompt, it will invoke your alias, but if you type

> echo ff

the ff is just an argument, not a command. (At least in bash, you can play some tricks if the alias definition ends with a space. See Stéphane Chazelas's answer for a possible solution if you're determined to use shell aliases.)

You typed

> gdb ff

so the shell invoked gdb, passing it the string ff as an argument.

You can pass arguments to the debugged program via the gdb command line, but you have to use the --args option. For example:

> gdb firefox --safe-mode

tries (and fails) to treat --safe-mode as an option to gdb. To run the command with an argument, you can do it manually:

> gdb firefox
...
(gdb) run --safe-mode

or, as thrig's answer reminds me, you can use --args:

> gdb --args firefox --safe-mode
...
(gdb) run

(The first argument following --args is the command name; all remaining arguments are passed to the invoked command.)

It's possible to extract the arguments from a shell alias, but I'd recommend just defining a separate alias:

alias ff='firefox --safe-mode'
alias gdbff='gdb --args firefox --safe-mode'

Or, better, use shell functions, which are much more versatile. The bash manual says:

For almost every purpose, shell functions are preferred over aliases.

7
  • 1
    I think if you enter alias gdb='gdb ' the trailing blank will make the shell consider the next word as an alias. Commented Feb 8, 2018 at 1:34
  • @MarkPlotnick: Not in bash, and I'm not aware that any other shell has that behavior. gnu.org/software/bash/manual/html_node/Aliases.html Commented Feb 8, 2018 at 3:32
  • 6
    Keith: from the second graf of that very page: "If the last character of the alias value is a blank, then the next command word following the alias is also checked for alias expansion." And the same from POSIX. Though in this case you need alias gdb='gdb --args '.Shell functions are usually better in the shell, and for bash even in child shells modulo shellshock, but not other programs like gdb. Commented Feb 8, 2018 at 5:50
  • 1
    @dave_thompson_085: I stand corrected. Commented Feb 8, 2018 at 6:57
  • 1
    I'd suggest editing the answer to remove the original assertion that "you can't pass arguments to the debugged program via the gdb command line" - someone could easily read the first part of the answer, get to that bit, and then give up believing that what they want to do is impossible (without seeing the update that tells them that it is :-)
    – psmears
    Commented Feb 8, 2018 at 14:58
5

Not directly but it is possible with some wrangling of ZSH shell aliases into a form suitable for gdb.

alias testtest='echo test test test'

function gdb-alias() {
   local cmdargs
   cmdargs=( ${(z)${aliases[$1]}} )
   gdb -q --args $cmdargs
}

This splits the alias (more robust code would check whether the first argument is indeed an alias, or even is set, etc) as ZSH would and then feeds those arguments to gdb via the handy --args flag (see info gdb invocation). If we then run gdb-alias testtest

% gdb-alias testtest
Reading symbols from echo...(no debugging symbols found)...done.
(gdb) r
Starting program: /Users/jhqdoe/usr/Darwin15.6.0-x86_64/bin/echo test test test
test test test
[Inferior 1 (process 93721) exited normally]
(gdb) 

which shows that echo (my assembly implementation of echo, anyways) was run by gdb with the arguments from the alias.

(This will probably break on global aliases, or any aliases with shell metacharacter foo, maybe, depending on whether gdb throws those argument through a shell compatible with anything that might be set in ZSH, but should be okay for simple x='y z' type stuff. Maybe.)

4

In POSIX shells, aliases are only expanded in command position (wherever a command is expected) or after aliases whose expansion ends in a blank character (in zsh, only a space, and in many other implementations, only space or tab)¹. You also need the --args option to gdb to be able to pass arguments to the program being debugged. So you can do:

alias gdba='gdb --args ' # note the trailing space which does mean
                         # that aliases are to be expanded after it
alias ff='firefox --safe-mode'
gdba ff

¹ zsh also supports global aliases (with alias -g) which are expanded in many more places, but you probably wouldn't want to use such an alias for your firefox --safe-mode here as you wouldn't want echo ff for instance to output anything other than ff.

1

You do not need aliases to try to get gdb accepting arguments.

In your case, it would be:

gdb firefox
(gdb) set args --safe-mode

Not the answer you're looking for? Browse other questions tagged .