Why does GDB start a new shell and how to disable

2019-04-25 09:55发布

问题:

I was figuring out a problem where starting the application from GDB results in a symbol lookup error, but starting it from the shell works.

It turns out that whenever you start a program from within GDB it will start a new shell and thus override all environment variables I had set before starting GDB (like LD_LIBRARY_PATH).

This is not really the behavior I want. Can someone explain the rationale behind this, or tell me how I can turn this off?

回答1:

I am guessing that you unconditionally set LD_LIBRARY_PATH in your ~/.cshrc or the like. So if from a shell prompt you do this:

export LD_LIBRARY_PATH=foo  # or for csh:
setenv LD_LIBRARY_PATH foo
$SHELL -c 'echo $LD_LIBRARY_PATH'

the result is something other than foo. Don't do that.

Usually this happens to CSH users, who neglected to protect their ~/.cshrc against non-interactive shells. It could also happen to BASH users who set their BASH_ENV.



回答2:

I meet the same problem. I find that in inferior.h (source code of gdb gdb/inferior.h) there is a macro STARTUP_WITH_SHELL, there is also a piece of comment as

/* If STARTUP_WITH_SHELL is set, GDB's "run"
   will attempts to start up the debugee under a shell.
   This is in order for argument-expansion to occur. E.g.,
   (gdb) run *
   The "*" gets expanded by the shell into a list of files.
   While this is a nice feature, it turns out to interact badly
   with some of the catch-fork/catch-exec features we have added.
   In particular, if the shell does any fork/exec's before
   the exec of the target program, that can confuse GDB.
   To disable this feature, set STARTUP_WITH_SHELL to 0.
   To enable this feature, set STARTUP_WITH_SHELL to 1.
   The catch-exec traps expected during start-up will
   be 1 if target is not started up with a shell, 2 if it is.
   - RT
   If you disable this, you need to decrement
   START_INFERIOR_TRAPS_EXPECTED in tm.h. */
#define STARTUP_WITH_SHELL 1
#if !defined(START_INFERIOR_TRAPS_EXPECTED)
#define START_INFERIOR_TRAPS_EXPECTED   2
#endif

Then I set STARTUP_WITH_SHELL as 0 and decremented START_INFERIOR_TRAPS_EXPECTED and recompiled my gdb. After that gdb didn't start from shell any more.



回答3:

When you start gdb from the shell, you start it as a new process, there's no way around that. In Unix new processes inherit some of the environment of the parent.

To make sure a variable is inherited, if you're using a bourne-like shell, try exporting it:

export LD_LIBRARY_PATH=...


回答4:

The debuggee (inferior in gdb parlance) is always started with a clean environment in order to get more reproducible results. In order to set a variable there, use the

set env VARNAME=VALUE

command before running.



标签: c gdb symbols