如何使用GDB分析故障转储文件

red*_*ver 7 linux debugging multithreading

我有一个在Cent OS下运行的服务器应用程序.服务器每秒响应许多请求,但每小时左右会反复崩溃并创建一个故障转储文件.情况非常糟糕,我需要尽快找出崩溃原因.

我怀疑问题是并发问题,但我不确定.我可以访问源代码和崩溃转储文件,但我不知道如何使用崩溃转储来指出问题.

任何建议都非常感谢.

Jon*_*ler 9

如果问题需要一个小时左右才能显现出来,那可能是内存问题 - 可能是耗尽,或者可能是践踏(例如使用已经释放的内存).

你说你有崩溃转储文件 - 这是一个核心转储?

假设你有一个核心转储,那么第一步应该是打印堆栈回溯:

gdb program core
> where
Run Code Online (Sandbox Code Playgroud)

这应该告诉你崩溃发生时程序的位置.还有什么可用取决于服务器的编译方式.如果可能,您应该在启用调试的情况下重新编译(使用-g带GCC 的' '标志).这将为您提供堆栈回溯的更多信息.

如果您的问题与内存有关,请考虑运行valgrind.

还要考虑使用调试版本构建和运行malloc().调试版本将检测正常版本错过或崩溃的内存滥用情况.


ale*_*gle 8

要查找的第一件事是程序崩溃时得到的错误消息.这通常会告诉您发生了什么样的错误.例如,"分段错误""SIGSEGV"几乎肯定意味着您的程序已取消引用NULL或其他无效指针.如果程序是用C++编写的,那么错误消息通常会告诉您任何未捕获的异常的名称.

如果没有看到错误消息,请从命令行运行程序,或将其输出通过管道传输到文件中.

为了使核心文件真正有用,您需要在没有优化和调试信息的情况下编译程序.海湾合作委员会需要以下选择:-g -O0.(确保您的构建没有任何其他-O选项.)

获得核心文件后,在gdb中打开它:

gdb YOUR-APP COREFILE
Run Code Online (Sandbox Code Playgroud)

键入where以查看发生崩溃的位置.您基本上处于正常的调试会话中 - 您可以检查变量,在堆栈中上下移动,在线程之间切换等等.

如果您的程序崩溃了,那么它可能是无效的内存访问 - 因此您需要查找具有零值的指针,或者指向看起来不好的数据的指针.您可能无法在堆栈的最底部找到问题,在找到问题之前,您可能需要将堆栈向上移动几个级别.

祝好运!


dic*_*oce 5

gdb -c core.file exename
bt
Run Code Online (Sandbox Code Playgroud)

假设它exename是使用调试符号构建的(并且它的所有动态依赖关系都在路径中),它将为您提供回溯跟踪.'up'和'down'将在堆栈中上下移动,p varname并可用于检查本地和参数.

您也可以尝试在valgrind下运行它:

valgrind --tool=memcheck --leak-check=full exename
Run Code Online (Sandbox Code Playgroud)