2011-07-17 38 views
4

我正在做snprintf并发生分段故障。了解分段故障的堆栈轨迹

当我加载核心文件在gdb像这样:gdb my_executable core;并做bt得到回溯,我得到了以下内容:

Program terminated with signal 11, Segmentation fault. 
#0 0x88207fc2 in memcpy() from /usr/lib/libc.so.6 
(gdb) bt 
#0 0x88207fc2 in memcpy() from /usr/lib/libc.so.6 
#1 0x88205eb6 in __sfvwrite() from /usr/lib/libc.so.6 
#2 0x881fbc95 in strchr() from /usr/lib/libc.so.6 
#3 0xbfbe6c14 in ??() 
#4 0xbfbe69d8 in ??() 
#5 0x881ed91e in localeconv() from /usr/lib/libc.so.6 
#6 0x881fec05 in __vfprintf() from /usr/lib/libc.so.6 
#7 0x881f7d80 in snprintf() from /usr/lib/libc.so.6 
#8 0x08052b64 in my_function (files=0xbfbed710, filename=<value optimized out>) at myfile.c:1102 
#9 0x08053bfb in main (argc=4, argv=0xbfbedd90) at myfile.c:225 

我在赛格故障的情况下,看到这样的堆栈很多次,但从来没有正确理解。

只看跟踪电话,我们可以告诉出了什么问题吗?

注意:请不要要求更多的代码。我的动机是简单地理解像这样的堆栈跟踪意味着什么 - 而不考虑代码。我看到顶部的“memcpy”失败了。我想了解在这种情况下何时会发生这种情况。

回答

7

您的功能在myfile.c:1102做了些什么。这反过来诱使标准库进入非法访问内存。操作系统通过sigsegv注意并拍摄您的程序。

的常见原因,(如图#2 :)))是:

  • 写入只读存储器
  • 使用未初始化的指针
  • 访问存储过去的分配块的结尾

功能的长长的清单显示你是谁做的。所以:

  • my_function称为snprintf
  • 呼吁__vfprintf
  • ...
+0

感谢您的“常见原因”。我正在寻找可能导致此类段错误的详尽列表。感谢您的帮助:) – hari

0

这只是一个呼叫的痕迹。程序中的第一个函数调用将出现在底部,一般为main,随后调用其他 函数(来自主函数)将出现在最上面。如果新的调用调用 另一个子程序(函数),它将堆积在顶部,并且过程继续。

考虑到GDB可用,GDB会打印一些有用的信息。第一列 是堆栈位置(上下)。第二列包含呼叫地址, ,其余信息包含呼叫功能的名称和 所在的位置。请注意,这些差异很大。有时, 符号的名称无法检索,??()将显示为您的堆栈 跟踪中的#3和#4。当来源可用时,功能定义的行也会出现,如at myfile.c:225

2

我建议你在Valgrind下运行你的可执行文件。它可能会输出addl呼叫跟踪,以防您的代码出现问题,例如处理已释放的内存。这通常有助于理解崩溃的原因。

+0

谢谢。你是否碰巧为Valgrind提供了一个很好的入门链接/指针? – hari

+1

Valgrind入门有[快速入门指南](http://valgrind.org/docs/manual/QuickStart.html)。有关详细信息,请参见[Valgrind用户手册](http://valgrind.org/docs/manual/manual.html)。请注意用户手册中的[Memcheck](http://valgrind.org/docs/manual/mc-manual.html)。这是内存错误检测器。它可以检测代码中与内存相关的问题的数量。 – ks1322

+0

非常感谢这些指针,将会对它们进行研究。 – hari