我有一个在Cent OS下运行的服务器应用程序。服务器每秒响应许多请求,但每小时左右会反复崩溃并创建一个故障转储文件。情况非常糟糕,我需要尽快找出崩溃原因。
我怀疑问题是并发问题,但我不确定。我可以访问源代码和崩溃转储文件,但我不知道如何使用崩溃转储来指出问题。
非常感谢任何建议。
答案 0 :(得分:9)
如果问题需要一个小时左右才能显现出来,那可能是内存问题 - 可能是耗尽,或者可能是践踏(例如使用已经释放的内存)。
你说你有崩溃转储文件 - 这是核心转储吗?
假设您有一个核心转储,那么第一步应该是打印堆栈回溯:
gdb program core
> where
这应该告诉你崩溃发生时程序的位置。还有什么可用取决于服务器的编译方式。如果可能,您应该在启用调试的情况下重新编译(使用GCC的“-g
”标志)。这将从堆栈回溯中为您提供更多信息。
如果您的问题与内存有关,请考虑使用valgrind
运行。
另请考虑使用malloc()
的调试版本构建和运行。调试版本将检测正常版本未命中或崩溃的内存滥用情况。
答案 1 :(得分:8)
要查找的第一件事是程序崩溃时收到的错误消息。这通常会告诉您发生了什么样的错误。例如,“分段错误”或“SIGSEGV”几乎肯定意味着您的程序已取消引用NULL或其他无效指针。如果程序是用C ++编写的,那么错误消息通常会告诉你任何未捕获的异常的名称。
如果没有看到错误消息,请从命令行运行程序,或将其输出通过管道传输到文件中。
为了使核心文件真正有用,您需要在没有优化和调试信息的情况下编译程序。 GCC需要以下选项:-g -O0
。 (确保您的构建没有任何其他-O
选项。)
获得核心文件后,使用以下命令在gdb中打开它:
gdb YOUR-APP COREFILE
键入where
以查看崩溃发生的位置。您基本上处于正常的调试会话中 - 您可以检查变量,在堆栈中上下移动,在线程之间切换等等。
如果您的程序崩溃了,那么它可能是无效的内存访问 - 因此您需要查找具有零值的指针,或者指向看起来不好的数据的指针。您可能无法在堆栈的最底部找到问题,在找到问题之前,可能需要将堆栈向上移动几层。
祝你好运!答案 2 :(得分:5)
gdb -c core.file exename
bt
假设exename
是使用调试符号构建的(并且它的所有动态依赖项都在路径中),它将为您提供回溯跟踪。 'up'和'down'将在堆栈中上下移动,p varname
可用于检查本地和参数。
您也可以尝试在valgrind下运行它:
valgrind --tool=memcheck --leak-check=full exename
答案 3 :(得分:0)
您的应用是否会创建核心文件?如果是这样,我会使用gdb来调试这个问题。