4

我正在使用嵌入式平台(架构为SH4),几分钟前我的程序因 SIGABRT 而崩溃。

幸运的是,我在 gdbserver 下运行,被这个信号中断的线程有这个堆栈转储:

#0  0x2a7f1678 in raise () from /home/[user]/target/lib/libc.so.6
#1  0x2a7f2a4c in abort () from /home/[user]/target/lib/libc.so.6
#2  0x2a81ade0 in __libc_message () from /home/[user]/target/lib/libc.so.6
#3  0x2a81f3a8 in malloc_printerr () from /home/[user]/target/lib/libc.so.6
#4  0x2a8c3700 in _IO_wide_data_2 () from /home/[user]/target/lib/libc.so.6

你知道这里发生了什么吗?一个糟糕的免费()?坏删除?坏的malloc?“_IO_wide_data_2”应该做什么?我看到了我也不理解的 malloc_printerr() 调用。

谷歌在这方面给了我234 个结果,但所有这些都只是因为这些人在他们的回溯中有那个“功能”。

4

3 回答 3

7

它是一个stderr支持广泛字符的流。

您可以将其分解为多个部分:

  • _IO: 输入输出。
  • wide_data: 宽数据
  • 2: 标准错误

你也有;

_IO_wide_data_0:标准输入 _IO_wide_data_1:标准输出

它们被链接为 2->1->0。

malloc_printerr()用于在动态内存管理中发生/捕获不良事件时打印各种错误消息。但是你的踪迹看起来是有上限的(你有没有删除任何东西?)。

这可能是对 stderr 的写入,您尝试在内存中、损坏的内存中、在……中写入一些东西。

或者它可能是较低的堆栈点导致写入 stderr。

或者……</p>

于 2012-04-22T10:54:13.067 回答
1

一个糟糕的免费()?坏删除?坏的malloc?

是的,我认为这是其中之一。

如果错误很容易重现,请在 malloc.c 中放置一个断点,malloc_printerr。当调试器停在那里时,您可能会获得完整的调用堆栈并在您的代码中找到错误的地方。我仍然不知道为什么会这样,进入 __libc_message 后,调用堆栈被破坏。


这就是我发现这种奇怪行为的方式。删除相同缓冲区两次的简单应用程序:

void main()
{
    char * buf = new char[4*1024];
    delete[] buf;
    delete[] buf;
}

在 malloc_printerr 中,调用堆栈如下所示:

#0  malloc_printerr (action=3, str=0x297d0b5c "double free or corruption (top)", ptr=<value optimized out>) at malloc.c:5887
#1  0x29750be8 in __libc_free (mem=0x411008) at malloc.c:3622
#2  0x29612c70 in operator delete (ptr=<value optimized out>) at ../../../../libstdc++-v3/libsupc++/del_op.cc:49
#3  0x29612cc2 in operator delete[] (ptr=<value optimized out>) at ../../../../libstdc++-v3/libsupc++/del_opv.cc:37
#4  0x0040068a in main (argc=1, argv=0x7bb26814) at double_free.cpp:47

输入 __libc_message 后:

#0  __libc_message (do_abort=2, fmt=0x297d09c8 "*** glibc detected *** %s: %s: 0x%s *** ") at ../sysdeps/unix/sysv/linux/libc_fatal.c:50
#1  0x2974f3a8 in malloc_printerr (action=3, str=0x297d0b5c "double free or corruption (top)", ptr=<value optimized out>) at malloc.c:5887
#2  0x297f3700 in _IO_wide_data_2 () from /cygdrive/c/STM/SH4-Linux-gcc/opt/STM/STLinux2.3/devkit/sh4/target/lib/libc.so.6
Backtrace stopped: frame did not save the PC

也许它与属性((noreturn))和编译器优化有关?

于 2012-07-26T15:42:33.430 回答
0

你能在 GDB 下运行时重现这个错误吗?您可以使用此处找到的各种“堆栈”命令获得更多堆栈跟踪信息:

GDB 备忘单

您可能需要向上或向下移动几个堆栈帧以确定发生了什么。

于 2012-04-24T23:29:49.387 回答