我有一个非常复杂的shell脚本,在其中调用我想通过GDB调试的C ++程序。将c ++程序与shell分离是非常困难的,因为它有很多分支和很多环境变量设置。
有没有办法在这个shell脚本上调用GDB?看起来像gdb
要求我直接调用C ++程序。
答案 0 :(得分:14)
您可以选择两个选项:
直接在shell脚本中调用GDB。这意味着您没有标准输入和标准输出重定向。
运行shell脚本,然后将调试器附加到已经运行的C ++进程,如下所示:gdb progname 1234
其中1234
是正在运行的C ++进程的进程ID。
如果你需要在程序开始运行之前做一些事情,那么选项1将是更好的选择,否则选项2是更清洁的方式。
答案 1 :(得分:12)
除了@ diverscuba23提到的选项外,您还可以执行以下操作:
gdb --args bash <script>
(假设它是一个bash脚本。否则相应调整)
答案 2 :(得分:3)
我可能会修改脚本以始终调用gdb(稍后再恢复)或添加一个选项来调用gdb。这几乎总是最简单的解决方案。
下一个最简单的方法是临时移动您的可执行文件并将其替换为在移动的程序上运行gdb的shell脚本。例如,在包含程序的目录中:
$ mv program _program
$ (echo "#!/bin/sh"; echo "exec gdb $PWD/_program") > program
$ chmod +x program
答案 3 :(得分:2)
修改c ++应用程序以打印其pid并休眠30秒(可能基于环境或参数)。使用gdb附加到正在运行的实例。
答案 4 :(得分:1)
您是否可以暂时将gdb
添加到您的脚本中?
答案 5 :(得分:0)
尽管给出的答案是有效的,但有时您无权更改脚本以执行gdb或修改程序以添加其他输出以通过pid附加。
幸运的是,通过bash的力量还有另一种方式
在执行后,使用ps,grep和awk为您挑选pid。您可以通过用自己的脚本包装其他脚本,也可以自己执行命令来完成此操作。
该命令可能看起来像这样:
process.sh
#!/usr/bin/env bash
#setup for this example
#this will execute vim (with cmdline options) as a child to bash
#we will attempt to attach to this process
vim ~/.vimrc
要附加gdb,我们只需执行以下命令:
gdb --pid $(ps -ef | grep -ve grep | grep vim | awk '{print $2}')
ps -ef
列出进程和的参数。有时,您将有一个程序正在运行的多个实例,并且需要进一步grep到所需的那个grep -ve grep
之所以存在,是因为ps的f
选项会将 next grep
包括在其列表中。如果您不需要命令参数进行其他过滤,请不要为ps包含-f
选项,而忽略此部分grep vim
是我们找到所需过程的地方。如果您需要更多过滤,则可以执行grep -E "vim.*vimrc"
之类的操作,然后过滤到您要附加的确切过程awk '{print $2}'
仅将进程的pid输出到stdout。如果您使用的是$1
而不是ps -e
,请使用ps -ef
我的正常设置是运行这样的脚本,该脚本在1 tmux窗格中启动我的进程,并在底部窗格中键入与上面类似的内容。这样,如果我出于某种原因需要调整过滤条件,就可以很快完成。
通常情况下,特定实例将是相同的,并且我想在启动后自动附加。我将改为执行以下操作:
runGdb.py
#!/usr/bin/env bash
./process.sh &
PID=$(ps -ef | grep -ve grep | grep -E "vim.*vimrc" | awk '{print $2}')
#or
#PID=$(ps -e | grep vim | awk '{print $1}')
gdb --pid $PID
这假定原始进程可以在后台安全运行。