【问题标题】:Use GDB to debug a C++ program called from a shell script使用 GDB 调试从 shell 脚本调用的 C++ 程序
【发布时间】:2011-06-30 04:56:19
【问题描述】:

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

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

【问题讨论】:

  • 该死的......同样的问题仍然存在。我认为一个简单的set follow-fork-mode child 将是我们需要做的所有事情来获得我们感兴趣的代码......

标签: c++ debugging shell gdb


【解决方案1】:

有两种选择:

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

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

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

【讨论】:

    【解决方案2】:

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

    gdb --args bash <script>
    

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

    【讨论】:

    • gdb 从上述方法开始,但我不能做任何事情,比如设置断点,因为它说“找不到符号表”。如何解决这个问题?
    • 那么您从终端发出的使用 gdb 启动代码的命令是什么?如果它说“未找到符号表”,可能只是意味着您需要使用调试符号构建代码,而不是
    【解决方案3】:

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

    【讨论】:

    • 睡眠 30 秒或更长时间等待按键。
    【解决方案4】:

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

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

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

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

        幸运的是,还有另一种方法可以利用 bash 的强大功能

        使用 ps、grep 和 awk 在 pid 执行后为您挑选出 pid。您可以通过用自己的脚本封装其他脚本或自己执行命令来做到这一点。


        该命令可能如下所示:

        进程.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}')

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

        我的正常设置是运行这样的脚本,该脚本在 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
        

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

        【讨论】:

          猜你喜欢
          • 2018-06-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-08-12
          相关资源
          最近更新 更多