我有一个从以太网端口读取数据并在其上运行一组算法的项目。该程序运行正常几个小时,然后产生下面显示的错误。
有人可以建议如何调试,找到导致错误的行吗?
*** 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]
谢谢!
基于第一条消息,一个特定竞技场的未排序块列表已损坏:
* 'objs/x64Linux3gcc5.4.0/lidarToBox' 中的错误: 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(受害者)"。 在您的情况下,使用 64 位进程,宏 chunk2mem 将添加 16,因此您可以将受害者的值重建为 0x00000000051fc640-16 = 0x00000000051fc630。
你可以看看受害者有什么:
x/4gx 0x00000000051fc630
显示的第二个值将是受害者>大小的值。
如果您碰巧有一个核心转储,您可能可以使用免费的开源工具 https://github.com/vmware/chap 来收集更多信息,因为 chap 经常在启动时检测到此类损坏。 要启动它,请使用:
章节核心文件路径
考虑到大小字段已损坏的可能性,了解在列为0x00000000051fc640的分配之前如何使用相邻分配也可能有所帮助。 损坏可能是由于先前分配的缓冲区溢出造成的。 若要查看上一个分配的内容,请从 chap 提示符键入显示分配 51fc630。 如果 chap 告诉您给定的地址不是分配的一部分,请使用 chap 提示符中的描述 51fc630来了解该分配可能是什么。
在破坏 valgrind 之前,使用 -ggdb3 调试标志编译你的程序
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
我使用 valgrind 来检测许多内存管理错误。