繁体   English   中英

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

[英]Debugging a running daemon using gdb

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

解释性说明:

  1. 我知道如何使用Attach命令将gdb附加到正在运行的进程

  2. 附加到该进程后,它将停止。 如果我运行然后“继续”,则在程序不崩溃的情况下,gdb仍会被阻止。 如果按CTRL-C,则该进程将退出,并且我无法简单地分离gdb。

所以问题是:有没有一种方法可以继续执行该过程,而不会阻塞gdb,但是如果该进程不崩溃,则能够分离该gdb?

尝试使用异步模式,然后选择“ 继续& ”:

将以下内容保存到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)

此页面上的attach / detach表示detach命令将在gdb

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

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

调试应用程序的另一种方法是使用核心文件进行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

注意:确保二进制文件是用调试符号编译的。

暂无
暂无

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

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