使用gdb调试正在运行的守护程序

时间:2013-04-23 12:10:03

标签: c linux gdb daemon

我正在开发一个作为守护进程运行的高流量网络C服务器应用程序。在某些情况下,应用程序崩溃(总是没有核心)。我如何使用gdb调试正在运行的守护进程来查找生成SIGSEGV的位置?

解释性说明:

  1. 我知道如何使用附加命令

  2. 将gdb附加到正在运行的进程
  3. 附加到流程后,它会停止。如果我运行然后“继续”,如果程序没有崩溃,gdb仍然被阻止。如果我按CTRL-C,进程正在退出,我无法简单地分离gdb。

  4. 所以问题是:有没有办法在没有gdb被卡住的情况下继续这个过程但是如果进程没有崩溃就可以分离?

3 个答案:

答案 0 :(得分:7)

尝试异步模式和“继续& ”:

将以下内容保存至 non-stop.gdb

set target-async on
set pagination off
set non-stop on

然后运行:

$ gdb -x non-top.gdb
(gdb) !pgrep YOUR-DAEMON
1234
(gdb) attach 1234
(gdb) continue -a &
(gdb)

答案 1 :(得分:3)

此页面attach/detach表示detach命令可在gdb内使用。

如果要在应用程序中捕获分段错误,则必须从调试器运行该应用程序。然后,当捕获到信号时,您可以使用wherebt来查看应用程序的堆栈跟踪。当然,在出现故障后你无法继续申请,它应该如何恢复?如果您希望尽快触发故障,可以连接到正在运行的进程并再次等待调试器中的故障。

如果您想在发生故障后进行堆栈跟踪,那么您确实需要一个核心文件,因为没有要附加的进程。现在,如果你的守护进程是作为系统的一部分启动的,那么可能很难让配置转储核心,而且你可能不希望其他应用程序在整个地方留下核心转储。那么我建议停止系统守护程序并在用户空间中再次启动它,然后你可以允许它转储核心。如果它作为系统的一部分启动真的很重要,那么看看守护进程的启动是否仅限于单个子shell并在该子shell中使用ulimit -c来设置适当的最大值核心转储的大小。

答案 2 :(得分:0)

调试应用程序的另一种方法是使用核心文件进行GDB调试。

要在发生分段时生成核心文件,您可以按照以下步骤操作:

1)将以下参数复制到运行守护程序的脚本中。

ulimit -c unlimited
mkdir -p <path_to_core_file>, eg : /etc/user/ankit/corefiles
chmod 777 /etc/user/ankit/corefiles
echo "/etc/user/ankit/corefiles/%e.%s.core" > /proc/sys/kernel/core_pattern

2)使用脚本运行您的应用程序,然后等待核心转储文件被创建。一旦获得核心转储,就可以按照上述以下步骤使用gdb进行调试。

3)使用GDB获取回溯

gdb -c <core_file>, where core_file is the file generated after segmentation fault

4)回溯

接下来,我们想知道程序崩溃时堆栈是什么。在gdb提示符下运行bt将给您回溯。如果gdb尚未为二进制文件加载符号,那么它将与“ ??????”类似地引发带有问号的错误。要解决此问题,您将必须加载符号。

这里是加载调试符号的方法。

symbol-file /path/to/binary
sharedlibrary

5)为所有线程获取backTrace

thread apply all bt full

注意:确保二进制文件已使用调试符号进行编译。