10

编辑完整源代码在这里:

http://code.seanwoods.com/reynard.fossil.cgi/artifact/0cc9cbfbe021c2ba86dcb4d0cf6ada52f0a80063

这里调用程序:

http://code.seanwoods.com/reynard.fossil.cgi/artifact/891405e62c95349aaf461dfb8ba82259f77fac9b

我有一个相对简单的内存分配失败了。该应用程序并不特别复杂,尽管它确实在一些地方分配了内存。它是 C,而不是 C++。我很肯定这是分配内存而不是释放内存的问题。

这是代码:

printf(":2 %d %d\n", initial_len, initial_len * sizeof(char));
o->data = (char*) malloc(initial_len * sizeof(char));
printf(":3 \n");

执行后,我得到:

:1
:2 1024 1024
*** glibc detected *** ./menv: corrupted double-linked list: 0x0000000001d14400 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x76d76)[0x7f680cfc4d76]
/lib/x86_64-linux-gnu/libc.so.6(+0x771ed)[0x7f680cfc51ed]
/lib/x86_64-linux-gnu/libc.so.6(+0x794d4)[0x7f680cfc74d4]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x70)[0x7f680cfc9b90]
./menv[0x403971]
./menv[0x40391d]
./menv[0x4030ec]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f680cf6cead]
./menv[0x401369]
======= Memory map: ========
00400000-00405000 r-xp 00000000 08:03 2621441                            /home/swoods/code/reynard/modules/stdlib/menv
00605000-00606000 rw-p 00005000 08:03 2621441                            /home/swoods/code/reynard/modules/stdlib/menv
00606000-00706000 rw-p 00000000 00:00 0 
01cfd000-01d3d000 rw-p 00000000 00:00 0                                  [heap]
7f6808000000-7f6808021000 rw-p 00000000 00:00 0 
7f6808021000-7f680c000000 ---p 00000000 00:00 0 
7f680cd38000-7f680cd4d000 r-xp 00000000 08:05 10354962                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f680cd4d000-7f680cf4d000 ---p 00015000 08:05 10354962                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f680cf4d000-7f680cf4e000 rw-p 00015000 08:05 10354962                   /lib/x86_64-linux-gnu/libgcc_s.so.1
7f680cf4e000-7f680d0ce000 r-xp 00000000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d0ce000-7f680d2ce000 ---p 00180000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d2ce000-7f680d2d2000 r--p 00180000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d2d2000-7f680d2d3000 rw-p 00184000 08:05 10354980                   /lib/x86_64-linux-gnu/libc-2.13.so
7f680d2d3000-7f680d2d8000 rw-p 00000000 00:00 0 
7f680d2d8000-7f680d2da000 r-xp 00000000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d2da000-7f680d4da000 ---p 00002000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d4da000-7f680d4db000 r--p 00002000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d4db000-7f680d4dc000 rw-p 00003000 08:05 10354973                   /lib/x86_64-linux-gnu/libdl-2.13.so
7f680d4dc000-7f680d4fc000 r-xp 00000000 08:05 10354984                   /lib/x86_64-linux-gnu/ld-2.13.so
7f680d6df000-7f680d6e2000 rw-p 00000000 00:00 0 
7f680d6f8000-7f680d6fb000 rw-p 00000000 00:00 0 
7f680d6fb000-7f680d6fc000 r--p 0001f000 08:05 10354984                   /lib/x86_64-linux-gnu/ld-2.13.so
7f680d6fc000-7f680d6fd000 rw-p 00020000 08:05 10354984                   /lib/x86_64-linux-gnu/ld-2.13.so
7f680d6fd000-7f680d6fe000 rw-p 00000000 00:00 0 
7ffff3bd6000-7ffff3bf7000 rw-p 00000000 00:00 0                          [stack]
7ffff3bff000-7ffff3c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
  • 代码编译没有问题。
  • 当我“独立”运行它时,它会因上述错误而崩溃。我看到:2但我没有看到 ,这告诉我这是malloc:3中的错误。(我希望我错了。)
  • 当我通过 运行相同的二进制文件时valgrind,它按预期工作。
  • 变量声明似乎不是问题o->data,它是一个 char*. 如果我声明char* A; A =而不是o->data =它仍然崩溃。

我将非常感谢有关如何排除故障/为什么会发生这种情况的任何想法。

谢谢!

4

2 回答 2

17

所以,我想我找到了。我们可能需要在“肖恩需要学习基本的 Valgrind 技能”下归档。这是我为任何未来的观察者解决它的方法。

  1. 好的,我们正在处理一个久经考验的库函数引发的一个非常奇怪的错误,所以它一定是我的设置特有的。算法是一样的,所以一定是数据
  2. 动态内存实现有一个底层数据结构来跟踪分配的内存,它恰好是一个双向链表——因此是消息。
  3. 所以,一定有一个内存操作以一种微妙的方式破坏了这个数据结构。
  4. 好的,我们可以使用哪些工具?Valgrind 受到高度赞扬,让我们尝试一下。奇怪,它在 Valgrind 中工作。唔。
  5. 实际阅读 Valgrind 告诉你的内容。(这是我没有尽我所能的地方。)它会用诸如“大小为 1 的无效写入”之类的错误以及出现的各种标签/符号的痕迹来标记您。寻找可能的错误并根据需要进行调整。
  6. 在这种情况下,它指向我调用memcpy()in 的hashtable_put 函数hashtable.c。微妙的提示是我使用 address-of 运算符将第一个参数传递给 memcpy &,这导致了损坏。
  7. 当我解决这个问题时,Valgrind 不再抱怨。

这个故事的主旨:

  • 不要忽视来自工具的反馈。没有消息 [通常] 是好消息,因此如果 Valgrind 吐出大量信息,那么问题的可能性就会增加。
  • 动态内存分配错误是微妙的(真正意义上的动态),并且可能受到许多变量的影响。Valgrind 把东西放在你的程序和内存库的中间,所以它知道发生了什么,所以我认为这些以某种方式影响了程序的操作。

到目前为止已经解决了这个问题的提交:

http://code.seanwoods.com/reynard.fossil.cgi/ci/bd6a5a23c1?sbs=0

于 2013-08-03T18:09:21.230 回答
-1

编辑:由于我们几乎不知道您的 struct o 是什么样的以及o->data应该是什么数据类型,我们只能推测您正在尝试做什么。

请指定o结构定义,以便我们提供帮助。

于 2013-08-03T17:03:24.573 回答