2013-04-23 193 views
6

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

解释性说明:

  1. 我知道如何使用gdb来连接到使用附加命令

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

所以问题是:有没有办法继续进程没有被卡住的gdb,但能够分离如果进程没有崩溃?

+0

您是否尝试过改变coredump设置与例如'ulimit'命令?和/或运行调试版本?或者可能添加更多日志记录来缩小可能的崩溃位置? – 2013-04-23 12:16:00

+0

我试过所有的可能性。 该进程在Ubuntu服务器上作为新贵服务运行,并在服务启动时被setuid-ed给某个用户。 limits.conf包含该用户的nofile和core的无限值。 我在/etc/sysctl.conf中设置了fs.suid_dumpable和kernel.core_uses_pid 我添加了更多的日志记录,但是它是一个高流量的服务器,它会产生太多的输出。 – 2013-04-23 12:19:06

回答

3

此页面attach/detach表示detach命令将在gdb内工作。

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

如果您想要在发生故障后进行堆栈跟踪,那么您确实需要一个核心文件,因为不需要附加任何进程。现在,如果您的守护进程作为系统的一部分启动,则可能很难将配置转储到内核,而且您可能不希望其他应用程序在整个地方留下核心转储。所以我建议停止系统守护进程并在用户空间中重新启动它,然后您可以允许它转储核心。如果它作为系统的一部分启动真的非常重要,那么请查看守护进程的启动是否局限于一个子外壳,并在该子外壳中使用ulimit -c来为内核设置适当的最大大小倾倒。

+0

我知道,但是在运行“continue”命令后,退出gdb的唯一方法是按CTRL-C,这会停止正在运行的进程。 – 2013-04-23 12:25:48

+0

使用'detach'而不是'continue',然后使用'quit'。适用于我。 – 2013-04-23 12:56:21

+0

我明白了,但如果进程崩溃,我希望能够获得回溯。 – 2013-04-23 13:40:27

6

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

保存下面非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) 
+0

谢谢。我会尝试这个,并会发布反馈。 – 2013-04-23 14:28:52