繁体   English   中英

使用 GDB 调试从 shell 脚本调用的 C++ 程序

[英]Use GDB to debug a C++ program called from a shell script

我有一个极其复杂的 shell 脚本,它在其中调用我想通过 GDB 调试的 C++ 程序。 将这个 c++ 程序与 shell 分开是非常困难的,因为它有很多分支和很多环境变量设置。

有没有办法在这个 shell 脚本上调用 GDB? 看起来gdb要求我直接调用 C++ 程序。

除了@diverscuba23 提到的选项之外,您还可以执行以下操作:

gdb --args bash <script>

(假设它是一个 bash 脚本。否则相应地进行调整)

您可以执行以下两个选项:

  1. 直接在 shell 脚本中调用 GDB。 这意味着您没有重定向标准输入和标准输出。

  2. 运行 shell 脚本,然后将调试器附加到已经运行的 C++ 进程,如下所示: gdb progname 1234其中1234是正在运行的 C++ 进程的进程 ID。

如果您需要在程序开始运行之前做一些事情,那么选项 1 将是更好的选择,否则选项 2 是更简洁的方法。

我可能会修改脚本以始终调用 gdb(并在稍后恢复)或添加一个选项来调用 gdb。 这几乎总是最简单的解决方案。

下一个最简单的方法是临时移动您的可执行文件并将其替换为在移动的程序上运行 gdb 的 shell 脚本。 例如,在包含您的程序的目录中:

$ mv program _program
$ (echo "#!/bin/sh"; echo "exec gdb $PWD/_program") > program
$ chmod +x program

修改 c++ 应用程序以打印其 pid 并休眠 30 秒(可能基于环境或参数)。 使用 gdb 附加到正在运行的实例。

您可以暂时将gdb添加到您的脚本中吗?

尽管给出的答案是有效的,但有时您无权更改脚本以执行 gdb 或修改程序以添加附加输出以通过 pid 附加。

幸运的是,还有另一种方式来发挥 bash 的威力

执行后,使用 ps、grep 和 awk 为您挑选 pid。 您可以通过用自己的脚本包装其他脚本或仅自己执行命令来完成此操作。


该命令可能如下所示:

进程文件

#!/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}')

  1. 我用ps -ef这里列出的过程他们的论点。 有时,您会运行一个程序的多个实例,并且需要进一步 grep 到您想要的那个
  2. grep -ve grep存在是因为 ps 的f选项将在其列表中包含下一个grep 如果您不需要额外过滤的命令参数,请不要在 ps 中包含-f选项并忽略此部分
  3. grep vim是我们找到所需进程的地方。 如果您需要更多过滤,您可以执行类似grep -E "vim.*vimrc"并过滤到您尝试附加到的进程
  4. awk '{print $2}'只是将进程的 pid 输出到标准输出。 如果您使用ps -e而不是ps -ef请使用$1

我的正常设置是运行这样的脚本,该脚本在 1 个 tmux 窗格中启动我的进程,并在底部窗格中键入类似于上述内容的内容。 这样,如果我需要调整过滤(无论出于何种原因),我都可以很快完成。


通常,对于特定实例,它是相同的,我想在它启动后自动附加。 我将改为执行以下操作:

运行Gdb文件

#!/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

这假设原始进程可以安全地在后台运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM