简体   繁体   English

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

[英]Debugging a running daemon using gdb

I am developing a high traffic network C server application that runs as a daemon. 我正在开发作为守护程序运行的高流量网络C服务器应用程序。 Under some circumstances, the app crashes (always without core). 在某些情况下,应用程序崩溃(总是没有内核)。 How I can debug the running daemon with gdb to find the place that generates the SIGSEGV? 如何使用gdb调试正在运行的守护程序,以找到生成SIGSEGV的位置?

Explanatory notes: 解释性说明:

  1. I know how to attach using gdb to a running process using attach command 我知道如何使用Attach命令将gdb附加到正在运行的进程

  2. After attaching to the process, it stops. 附加到该进程后,它将停止。 If I run then "continue", gdb remains blocked if the program does not crash. 如果我运行然后“继续”,则在程序不崩溃的情况下,gdb仍会被阻止。 If I press CTRL-C, the process is exiting and I am unable to simply detach gdb. 如果按CTRL-C,则该进程将退出,并且我无法简单地分离gdb。

So the question is: is there a way to continue the process without the gdb being stuck but being able to detach if the process does not crash? 所以问题是:有没有一种方法可以继续执行该过程,而不会阻塞gdb,但是如果该进程不崩溃,则能够分离该gdb?

Try async mode and " continue & ": 尝试使用异步模式,然后选择“ 继续& ”:

Save below to non-stop.gdb 将以下内容保存到non-stop.gdb

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

Then run: 然后运行:

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

This page attach/detach says that the detach command would work inside gdb . 此页面上的attach / detach表示detach命令将在gdb

If you want to catch a segmentation fault in an application, you will have to run the application from the debugger. 如果要捕获应用程序中的分段错误,则必须从调试器运行该应用程序。 Then when the signal is caught you can use where or bt to see a stack trace of the application. 然后,当捕获到信号时,您可以使用wherebt查看应用程序的堆栈跟踪。 Of course you can not continue the application after it faulted, how should it recover? 当然,您在出现故障后无法继续应用程序,应如何恢复? If you expect to trigger the fault soon, you can attach to the running process and again await the fault in the debugger. 如果希望很快触发故障,则可以附加到正在运行的进程,然后再次在调试器中等待故障。

If you want a stack trace after the fault occurred, then you really need a core file as there will be no process to attach to. 如果您希望在故障发生后进行堆栈跟踪,那么您确实需要一个核心文件,因为将没有附加过程。 Now if your daemon is started as part of the system it may be hard to get the configuration to dump core, plus you may not want other applications to leave core dumps all over the place. 现在,如果守护程序是作为系统的一部分启动的,则可能很难获得转储核心的配置,而且您可能不希望其他应用程序到处都留下核心转储。 So then I'd advice to stop the system daemon and start it again in your user space, then you can allow it to dump core. 因此,我建议您停止系统守护程序,然后在您的用户空间中再次启动它,然后可以允许其转储核心。 If it is really essential that it starts up as part of the system, then see if the start-up of the daemon is confined to a single sub-shell and use ulimit -c in that sub-shell to set an appropriate maximum size for the core dump. 如果确实需要将其作为系统的一部分启动,则请查看守护程序的启动是否仅限于单个子shell,并在该子shell中使用ulimit -c设置适当的最大大小,以用于核心转储。

Another method to debug your application is to use the core file for debugging with GDB. 调试应用程序的另一种方法是使用核心文件进行GDB调试。

To generate a core file when segmentation occurs you can follow the below steps: 要在发生分段时生成核心文件,可以按照以下步骤操作:

1) Copy the below parameters to your script which runs the daemon. 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) Run your application using the script and wait for the core dump file to be created. 2)使用脚本运行您的应用程序,然后等待核心转储文件被创建。 Once you get the core dump you can debug with gdb following the below steps as mentioned. 一旦获得核心转储,就可以按照以下提到的步骤使用gdb进行调试。

3) Getting backtrace using GDB 3)使用GDB获取回溯

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

4) Backtrace 4)回溯

Next, we want to know what the stack was when the program crashed. 接下来,我们想知道程序崩溃时堆栈是什么。 Running bt at the gdb prompt will give you a backtrace. 在gdb提示符下运行bt将给您回溯。 If gdb hadn't loaded symbols for the binary, so it will throw an error with the question mark similarly to this "??????". 如果gdb尚未为二进制文件加载符号,则它将与该“ ??????”类似地引发带有问号的错误。 To fix this you will have to load symbols. 要解决此问题,您将必须加载符号。

Here's how to load debugging symbols. 这是加载调试符号的方法。

symbol-file /path/to/binary
sharedlibrary

5) Get backTrace for all the threads 5)获取所有线程的backTrace

thread apply all bt full

NOTE: Make sure the binary is compiled with debugging symbols. 注意:确保二进制文件是用调试符号编译的。

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

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