了解分段错误的堆栈跟踪
我正在执行 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”失败了。我想了解在这种情况下什么时候会发生这种情况。
I am doing an snprintf
and getting a seg fault.
when I loaded the core file on gdb like this: gdb my_executable core
; and did bt
to get the backtrace, I got following:
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
I see such stack many times in case of seg fault but never understood correctly.
Just looking the calls in trace, can we tell what is going wrong?
NOTE: Please do not ask for more code. My motive is simply understand what the stack-trace like this means - irrespective of code. I see that on the top "memcpy" is failing. I want to understand when that can happen in this situation.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的函数在
myfile.c:1102
执行某些操作。这反过来又欺骗标准库非法访问内存。操作系统注意到并用sigsegv
标记您的程序。常见原因(如 Stackoverflow 上所示:)) )包括:
长长的函数列表会显示是谁执行的操作。所以:
my_function
调用了snprintf
,__vfprintf
You function does something at
myfile.c:1102
. This in turn tricks the standard library into illegally accessing memory. The operating system notices and slaps your program withsigsegv
.Common reasons, (as seen on Stackoverflow :)) ) are:
The long list of functions shows you who did it. So:
my_function
calledsnprintf
__vfprintf
我建议您在 Valgrind 下运行可执行文件。如果代码中出现问题(例如使用已释放的内存),它可能会输出额外的调用跟踪。这通常有助于了解崩溃的原因。
I would suggest you to run your executable under Valgrind. It may output additionl call traces in case of problems in your code such as work with already freed memory. This usually helps to understand the reason of crash.
这只是通话的痕迹。程序中的第一个函数调用将
出现在底部,一般会是
main
以及后续对其他的调用函数(来自 main 内部)将出现在其顶部。如果新的电话来电
另一个子例程(函数),它堆叠在顶部并且该过程继续。
GDB 打印一些有用的信息,考虑到它是可用的。第一栏
是堆栈位置(从上到下)。第二列包含呼叫地址,
其余信息包含调用的函数的名称和
它位于哪里。请注意,这些差异很大。有时,名字
无法检索符号并且
?? ()
将在堆栈上显示为 #3 和 #4痕迹。当源可用时,还有定义函数的行
将出现,如
at myfile.c:225
。It's just a trace of the calls. The first function call in the program will
appear in the bottom, generally it will be
main
and subsequent calls to otherfunctions (from inside main) will appear on top of it. If the new call calls
another subroutine (function), it's stacked on top and the process continues.
GDB prints some useful information, considering it's available. The first column
are the stack positions (top-bottom). Second column contains addresses of calls,
and the remaining information contains the name of the function called and
where it's located. Note that these vary a lot. Sometimes, the name of the
symbol can't be retrieved and
?? ()
will appear as in #3 and #4 on your stacktrace. When the source is available, also the line where the function is defined
will appear, like
at myfile.c:225
.