【问题标题】:How to run gdb against a daemon in the background?如何在后台对守护进程运行 gdb?
【发布时间】:2011-01-04 06:41:54
【问题描述】:

我正在尝试调试我用 gdb 编写的服务器,因为它在非常特定和罕见的情况下会出现段错误。

有什么方法可以让 gdb 在后台运行(通过安静模式或批处理模式?),跟随子进程(因为我的服务器是一个守护进程并与主 PID 分离)并自动转储核心和回溯(到指定文件)一旦程序崩溃?

【问题讨论】:

标签: c++ linux debugging unix gdb


【解决方案1】:

假设您有适当的权限,您可以将 gdb 附加到任何进程。您可以在命令行上使用:

gdb /path/to/binary _pid_

或在 gdb 中使用 attach 命令:

attach _pid_

因此,一旦您的守护程序启动,您可以使用这些技术中的任何一种来附加到您的守护程序运行的最终 PID。附加 gdb 会停止您正在跟踪的进程,因此您需要发出“继续”来重新启动它。

我不知道在程序崩溃时让 gdb 运行任意命令的直接方法。这是我能想到的一种解决方法:

  1. 为 SIGSEGV 创建和注册信号处理程序。
  2. 告诉 gdb 不要在该信号上停止 (handle SIGSEGV nostop)
  3. 在信号处理程序的第一行设置断点。
  4. 从第 3 步分配 commands to the breakpoint

【讨论】:

    【解决方案2】:

    为什么不在持久屏幕会话中以交互方式运行该进程?为什么调试时必须是守护进程?或者只是在屏幕会话中运行 gdb 并在它分叉后将其附加到正在运行的进程(例如 gdb /path/to/binary -p PID_of_binary)。

    【讨论】:

    • 这实际上是一个好主意,不知道为什么我没有想到这个:P 感谢您的基本解决方案!
    【解决方案3】:

    首先,我会设置您的外壳/环境以提供核心转储。在 bash 中:

    ulimit -c unlimited
    

    获得核心转储后,您可以使用 gdb 检查堆栈跟踪:

    gdb /path/to/app /path/to/core/file
    

    【讨论】:

    • 请注意,拥有核心文件与在调试器下停止相同的进程不同。核心文件不保留有关打开文件描述符或内存映射状态的信息。所以这并不总是一个有用的建议。
    • 并且不能调用程序中定义的函数。
    【解决方案4】:

    我并不是真正的 gdb 专家,但我想到了两件事

    1. Tracepoints 可能会在程序运行时为您提供必要的信息或
    2. 使用 gdb 的 remote debugging facility 在程序作为守护程序运行时对其进行调试。

    【讨论】:

      【解决方案5】:

      How to generate a stacktrace when my gcc C++ app crashes 这个问题的答案应该做你想做的事。 (假设您可以更改您的代码)

      【讨论】:

        【解决方案6】:

        您可能想看看 Samba 如何促进调试;它有一个可配置的"panic action",可以暂停应用程序、通知开发人员、生成 gdb 等,并作为其信号处理程序的一部分运行。请参阅 Samba 源代码树中的 lib/util/fault.c

        【讨论】:

          【解决方案7】:

          我的做法:注释掉daemon函数调用,重建二进制,然后用gdb运行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-03-26
            • 1970-01-01
            • 1970-01-01
            • 2013-04-16
            • 1970-01-01
            • 2020-08-23
            • 2023-03-02
            相关资源
            最近更新 更多