C语言 malloc() 崩溃,说损坏的双链表

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18035080/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:03:38  来源:igfitidea点击:

malloc() crashes, saying corrupted double-linked list

cmalloc

提问by Sean Woods

EditFull source is here:

编辑完整源代码在这里:

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

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

Calling program here:

在这里调用程序:

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

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

I've got a relatively simple memory allocation that's failing. The application is not particularly complicated although it does allocate memory in a few places. It's C, not C++. I'm positive this is an issue allocatingmemory, not freeingmemory.

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

Here's the code:

这是代码:

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

Upon execution, I get:

执行后,我得到:

: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
  • The code compiles without issue.
  • When I run it "standalone," it crashes with the error above. I see :2but I don't see :3, which tells me it's an error within malloc. (I hope I'm wrong.)
  • When I run the same binary through valgrind, it works as expected.
  • It does not appear to be an issue with the variable declaration o->data, which is a char*. If I declare char* A; A =instead of o->data =it still crashes.
  • 代码编译没有问题。
  • 当我“独立”运行它时,它会因上述错误而崩溃。我看到了,:2但我没有看到 :3,这告诉我这是malloc 中的错误。(我希望我是错的。)
  • 当我通过 运行相同的二进制文件时valgrind,它按预期工作。
  • 它似乎不是变量声明的问题o->data,它是一个 char*. 如果我声明char* A; A =而不是o->data =它仍然崩溃。

I would greatly appreciate any ideas as to how to troubleshoot/why this happens.

我将不胜感激关于如何解决/为什么会发生这种情况的任何想法。

Thanks!

谢谢!

回答by Sean Woods

So, I think I found it. We may need to file this under "Sean needs to learn basic Valgrind skills." Here's how I solved it for any future observers.

所以,我想我找到了。我们可能需要将此提交到“Sean 需要学习基本的 Valgrind 技能”下。这是我为任何未来的观察者解决它的方法。

  1. Okay, we're dealing with a really strange error thrown by a tried and tested library function, so it must be something specific to my setup. The algorithm is the same, so it must be the data.
  2. The dynamic memory implementation has an underlying data structure to track allocated memory, which happens to be a doubly linked list -- thus the message.
  3. So, there must be a memory operation somewhere that corruptsthis data structure in a subtle way.
  4. Okay, what tools do we have at our disposal? Valgrind is highly praised, let's try that. Strange, it works in Valgrind. Hmm.
  5. Actually read what Valgrind is telling you. (This is where I didn't do my part.) It flags you with errors such as "Invalid write of size 1" along with a trace of the various labels/symbols where this shows up. Look for possible errors and adjust as necessary.
  6. In this case, it was pointing me to an invocation of memcpy()in the hashtable_putfunction of hashtable.c. The subtle hint is that I was passing the first argument to memcpy using the address-of operator &, which caused the corruption.
  7. When I fixed that, Valgrind no longer complained.
  1. 好的,我们正在处理一个由久经考验的库函数抛出的一个非常奇怪的错误,所以它一定是我的设置所特有的。算法是一样的,所以肯定是数据
  2. 动态内存实现有一个底层数据结构来跟踪分配的内存,它恰好是一个双向链表——因此是消息。
  3. 因此,在某处一定有一个内存操作以一种微妙的方式破坏了这个数据结构。
  4. 好的,我们有哪些工具可供使用?Valgrind 受到高度赞扬,让我们尝试一下。奇怪,它适用于 Valgrind。唔。
  5. 实际阅读 Valgrind 告诉您的内容。(这是我没有做我的部分的地方。)它会向您标记错误,例如“大小为 1 的无效写入”以及出现此问题的各种标签/符号的跟踪。查找可能的错误并根据需要进行调整。
  6. 在这种情况下,它指向我memcpy()在 的hashtable_put函数中调用hashtable.c。微妙的提示是我使用 address-of operator 将第一个参数传递给 memcpy &,这导致了损坏。
  7. 当我解决这个问题时,Valgrind 不再抱怨。

The moral of the story:

这个故事的主旨:

  • Don't ignore feedback from the tools. No news is [usually] good news, so if Valgrind spits out lots of info their is an increased likelihood of a problem.
  • Dynamic memory allocation bugs are subtle (dynamicin the true sense of the word) and can be affected by many variables. Valgrind puts things in the middle of your program and the memory library so it knows what's going on, so I think these affected the program's operation somehow.
  • 不要忽视来自工具的反馈。没有消息 [通常] 是好消息,所以如果 Valgrind 吐出大量信息,那么出现问题的可能性就会增加。
  • 动态内存分配错误是微妙的(真正意义上的动态)并且会受到许多变量的影响。Valgrind 把东西放在你的程序和内存库的中间,所以它知道发生了什么,所以我认为这些以某种方式影响了程序的运行。

The commit that has so far fixed the issue:

到目前为止已解决问题的提交:

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

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

回答by DaMachk

EDIT: As we have almost no idea what your struct o looks like and what datatype o->datashould be, we can only speculae what you're trying to do.

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

Please specify the ostruct definition, so we can help.

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