为啥 GDB 会启动一个新的 shell 以及如何禁用这种行为?
Posted
技术标签:
【中文标题】为啥 GDB 会启动一个新的 shell 以及如何禁用这种行为?【英文标题】:Why does GDB start a new shell and how to disable this behaviour?为什么 GDB 会启动一个新的 shell 以及如何禁用这种行为? 【发布时间】:2012-02-11 06:34:10 【问题描述】:我正在解决一个问题,即从 GDB 启动应用程序会导致符号查找错误,但从 shell 启动它可以正常工作。
事实证明,无论何时你从 GDB 中启动一个程序,它都会启动一个新的 shell,从而覆盖我在启动 GDB 之前设置的所有环境变量(如 LD_LIBRARY_PATH
)。
这不是我真正想要的行为。有人可以解释这背后的理由,或者告诉我如何关闭它吗?
【问题讨论】:
【参考方案1】:我猜你无条件地在你的~/.cshrc
等中设置了LD_LIBRARY_PATH
。因此,如果您在 shell 提示下执行以下操作:
export LD_LIBRARY_PATH=foo # or for csh:
setenv LD_LIBRARY_PATH foo
$SHELL -c 'echo $LD_LIBRARY_PATH'
结果不是foo
。不要这样做那个。
这通常发生在 CSH 用户身上,他们忽略了保护他们的 ~/.cshrc
免受非交互式 shell 的攻击。设置BASH_ENV
的 BASH 用户也可能发生这种情况。
【讨论】:
我刚刚在我的配置中遇到了这个确切的错误。【参考方案2】:我遇到了同样的问题。我在inferior.h中找到了(gdb的源代码gdb/inferior.h)
有一个宏STARTUP_WITH_SHELL
,还有一条评论为
/* 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
然后我将 STARTUP_WITH_SHELL
设置为 0 并递减 START_INFERIOR_TRAPS_EXPECTED
并重新编译了我的 gdb。之后 gdb 不再从 shell 启动。
【讨论】:
当前 gdb 允许您通过以下方式进行操作:set startup-with-shell off
【参考方案3】:
当您从 shell 启动 gdb 时,您将它作为一个新进程启动,这是没有办法的。在 Unix 中,新进程继承了父进程的一些环境。
为确保变量被继承,如果您使用的是类似 bourne 的 shell,请尝试将其导出:
export LD_LIBRARY_PATH=...
【讨论】:
我猜问题是 OP 将他的LD_LIBRARY_PATH
设置为 ~/.bashrc
或类似的东西,并且该设置 覆盖 他在调用 GDB 之前设置的任何内容,] .
你成功了,@EmployedRussian !【参考方案4】:
调试对象(gdb 用语中的inferior)总是从干净的环境开始,以便获得更多可重现的结果。为了在那里设置一个变量,使用
set env VARNAME=VALUE
运行前的命令。
【讨论】:
如果你所说的“干净的环境”指的不是 GDB 自身环境的副本(加上已经执行的任何set env
命令),那么你就大错特错了。以上是关于为啥 GDB 会启动一个新的 shell 以及如何禁用这种行为?的主要内容,如果未能解决你的问题,请参考以下文章
GDB怎么调试使用.sh(shell脚本)启动的程序?(未完成,待测试)
GDB怎么调试使用.sh(shell脚本)启动的程序?(未完成,待测试)
为啥我在启动一个新的 Django 项目时会收到“ImportError: cannot import name find_spec”?