了解分段错误的堆栈跟踪

发布于 2024-11-24 18:23:21 字数 995 浏览 1 评论 0原文

我正在执行 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝眼睛不忧郁 2024-12-01 18:23:21

您的函数在 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 with sigsegv.

Common reasons, (as seen on Stackoverflow :)) ) are:

  • Writing to read-only memory
  • Using uninitialized pointers
  • Accessing memory past the end of an allocated block

The long list of functions shows you who did it. So:

  • my_function called snprintf
  • which called __vfprintf
  • ...
°如果伤别离去 2024-12-01 18:23:21

我建议您在 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.

迟到的我 2024-12-01 18:23:21

这只是通话的痕迹。程序中的第一个函数调用将
出现在底部,一般会是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 other
functions (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 stack
trace. When the source is available, also the line where the function is defined
will appear, like at myfile.c:225.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文