如何找到导致“malloc():内存损坏的行:0x00”

时间:2018-03-23 06:13:08

标签: c++ memory-leaks memory-corruption

我有一个从以太网端口读取数据并在其上运行一组算法的项目。程序运行良好几个小时,然后产生以下显示的错误。

有人可以建议如何调试,找到导致错误的行吗?

   *** Error in `objs/x64Linux3gcc5.4.0/lidarToBoxes': malloc(): memory corruption: 0x00000000051fc640 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f230dc167e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8213e)[0x7f230dc2113e]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f230dc23184]
/usr/lib/nvidia-384/tls/libnvidia-tls.so.384.111(+0x24c0)[0x7f2304e6e4c0]

======= Memory map: ========
00400000-00dc6000 r-xp 00000000 08:03 38407960                           /home/sai/sai_workspace/avt_17_003/modules/lidarToBoxes/objs/x64Linux3gcc5.4.0/lidarToBoxes
00fc5000-00fcf000 r--p 009c5000 08:03 38407960                           /home/sai/sai_workspace/avt_17_003/modules/lidarToBoxes/objs/x64Linux3gcc5.4.0/lidarToBoxes
00fcf000-00fd5000 rw-p 009cf000 08:03 38407960                           /home/sai/sai_workspace/avt_17_003/modules/lidarToBoxes/objs/x64Linux3gcc5.4.0/lidarToBoxes
00fd5000-00ff0000 rw-p 00000000 00:00 0 
0220b000-0614a000 rw-p 00000000 00:00 0     
[heap]

7f22d0000000-7f22d0022000 rw-p 00000000 00:00 0 
7f22d0022000-7f22d4000000 ---p 00000000 00:00 0 
7f22d4000000-7f22d4021000 rw-p 00000000 00:00 0 
7f22d4021000-7f22d8000000 ---p 00000000 00:00 0 
7f22d8000000-7f22d8021000 rw-p 00000000 00:00 0 
7f22d8021000-7f22dc000000 ---p 00000000 00:00 0 
7f22dc000000-7f22dc07c000 rw-p 00000000 00:00 0 
7f22dc07c000-7f22e0000000 ---p 00000000 00:00 0 
7f22e0000000-7f22e0021000 rw-p 00000000 00:00 0 
7f22e0021000-7f22e4000000 ---p 00000000 00:00 0 
7f22e6ffe000-7f22e6fff000 ---p 00000000 00:00 0 
7f22e6fff000-7f22e77ff000 rwxp 00000000 00:00 0 
7f22e8000000-7f22e8021000 rw-p 00000000 00:00 0 
7f22e8021000-7f22ec000000 ---p 00000000 00:00 0 
7f22eeffe000-7f22eefff000 ---p 00000000 00:00 0 
7f22eefff000-7f22ef7ff000 rwxp 00000000 00:00 0 
7f22ef7ff000-7f22ef800000 ---p 00000000 00:00 0 
7f22ef800000-7f22f0000000 rwxp 00000000 00:00 0 
7f22f0000000-7f22f00a6000 rw-p 00000000 00:00 0 
7f22f00a6000-7f22f4000000 ---p 00000000 00:00 0 
7f22f4000000-7f22f4021000 rw-p 00000000 00:00 0 
7f22f4021000-7f22f8000000 ---p 00000000 00:00 0 
7f22f8000000-7f22f8021000 rw-p 00000000 00:00 0 
7f22f8021000-7f22fc000000 ---p 00000000 00:00 0 
7f22fc093000-7f22fc291000 rw-p 00000000 00:00 0 
7f22fc291000-7f22fc491000 rw-s 00000000 00:09 323133    
socket:[323133]

谢谢!

3 个答案:

答案 0 :(得分:1)

根据第一条消息,某个特定领域的未排序块的列表已损坏:

*`objs / x64Linux3gcc5.4.0 / lidarToBoxes'出错:malloc():内存损坏:0x00000000051fc640 *

你可以看到它说“malloc():内存损坏”而不是,例如“malloc():内存损坏(快速)”。消息末尾的值在glibc的发行版之间有所不同,但在您的特定情况下,您看到的是来自代码的“受害者”的值,如下所示:

while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
  bck = victim->bk;
  if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)
      || __builtin_expect (victim->size > av->system_mem, 0))
    malloc_printerr (check_action, "malloc(): memory corruption",
                     chunk2mem (victim));
  size = chunksize(victim);

在我的特殊情况下,我从glibc-2.18 / malloc / malloc.c中抓取了这个,因为基于你在消息后面有一个数字的事实,你的glibc版本似乎接近5.18但这只是猜测。你的回溯指定“/lib/x86_64-linux-gnu/libc.so.6”作为库,这有点模糊,但如果你想找到更具体的信息,一种方法是做这样的事情:

ls -l /lib/x86_64-linux-gnu/libc.so.6

输出可能会显示您的路径是符号链接,并且该链接的目标将提供更多信息。在这种情况下,我认为你真的不需要知道确切的版本,但如果你看到来自libc malloc的错误消息并希望了解其含义,那么它将允许你下载匹配的glibc源。

回到代码显示的是“受害者”被设置为指向由av识别的竞技场的双向链表的最后一个条目。它还向您显示该行末尾的值来自“chunk2mem(victim)”。在您的情况下,使用64位进程,宏chunk2mem正在添加16,因此您可以将受害者的值重建为0x00000000051fc640-16 = 0x00000000051fc630。

您可以通过以下方式查看受害者:

x / 4gx 0x00000000051fc630

显示的第二个值是victim-&gt; size的值。

如果您碰巧有核心转储,您可以使用免费的开源工具https://github.com/vmware/chap来收集更多信息,因为chap经常在启动时检测到这种损坏。要启动它,请使用:

chap core-file-path

考虑到大小字段被破坏的可能性,理解如何使用列在0x00000000051fc640之前的相邻分配也是有帮助的。可能是腐败是由于先前分配的缓冲区溢出造成的。要查看上一个分配的内容,请在chap提示符下键入 show allocation 51fc630 。如果chap告诉您给定地址不是分配的一部分,请使用chap提示中的 describe 51fc630 来了解该分配可能是什么。

答案 1 :(得分:0)

在破坏valgrind之前使用-ggdb3 debug flag

编译程序
gcc -o executable -std=c11 -Wall -ggdb3 main.c

要运行valgrind,请将可执行文件作为参数传递

valgrind --leak-check=full \
         --show-leak-kinds=all \
         --track-origins=yes \
         --verbose \
         --log-file=valgrind-out.txt \
         ./executable

答案 2 :(得分:-2)

我使用valgrind来检测许多内存管理错误。