首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >‘损坏的双向链表’是什么意思

‘损坏的双向链表’是什么意思
EN

Stack Overflow用户
提问于 2013-02-15 22:45:43
回答 6查看 145K关注 0票数 49

我最近从我的PHP中得到了以下错误:

代码语言:javascript
复制
WARNING: [pool www] child 42475 said into stderr: "*** glibc detected *** php-fpm: pool www: corrupted double-linked list: 0x00000000013fe680 ***"

我对这个问题不是很感兴趣,也不是很感兴趣。但我很有兴趣理解这个错误‘损坏的双向链表’的实际含义,因为我以前没有见过它。我相信我知道什么是双向链表,但是我没能产生一个触发这个错误的程序。

有没有人能给我提供一个简短的代码片段,当我编译和执行glibc时,它会显示‘损坏的双向链表’?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2013-02-18 15:23:20

我自己找到了问题的答案:)

所以我不明白的是glibc是如何区分Segfault和损坏的双向链表的,因为根据我的理解,从glibc的角度来看,它们看起来应该是一样的。因为如果我在程序中实现了一个双向链表,glibc怎么可能知道这是一个双向链表,而不是任何其他结构呢?它可能不能,所以这就是我困惑的原因。

现在,我已经查看了glibc代码中的malloc/malloc.c,并且看到了以下内容:

代码语言:javascript
复制
1543 /* Take a chunk off a bin list */
1544 #define unlink(P, BK, FD) {                                            \
1545   FD = P->fd;                                                          \
1546   BK = P->bk;                                                          \
1547   if (__builtin_expect (FD->bk != P || BK->fd != P, 0))                \
1548     malloc_printerr (check_action, "corrupted double-linked list", P); \
1549   else {                                                               \
1550     FD->bk = BK;                                                       \
1551     BK->fd = FD;                                                       \

所以现在这突然变得有意义了。glibc可以知道这是一个双向链表的原因是因为该列表是glibc本身的一部分。我一直很困惑,因为我认为glibc可以以某种方式检测到一些编程正在构建一个双向链表,我不明白它是如何工作的。但是,如果它正在讨论的这个双向链表是glibc本身的一部分,那么它当然可以知道这是一个双向链表。

我仍然不知道是什么触发了这个错误。但至少我理解了损坏的双向链表和Segfault之间的区别,以及glibc如何知道这个结构应该是一个双向链表:)

票数 69
EN

Stack Overflow用户

发布于 2015-02-27 18:12:10

Heap overflow应该是corrupted double-linked listmalloc(): memory corruptiondouble free or corruption (!prev)-like glibc警告的罪魁祸首(但不总是)。

它应该通过以下代码重现:

代码语言:javascript
复制
#include <vector>

using std::vector;


int main(int argc, const char *argv[])
{
    int *p = new int[3];
    vector<int> vec;
    vec.resize(100);
    p[6] = 1024;
    delete[] p;
    return 0;
}

如果使用g++ (4.5.4)编译:

代码语言:javascript
复制
$ ./heapoverflow
*** glibc detected *** ./heapoverflow: double free or corruption (!prev): 0x0000000001263030 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7af26)[0x7f853f5d3f26]
./heapoverflow[0x40138e]
./heapoverflow[0x400d9c]
./heapoverflow[0x400bd9]
./heapoverflow[0x400aa6]
./heapoverflow[0x400a26]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x7f853f57b4bd]
./heapoverflow[0x4008f9]
======= Memory map: ========
00400000-00403000 r-xp 00000000 08:02 2150398851                         /data1/home/mckelvin/heapoverflow
00602000-00603000 r--p 00002000 08:02 2150398851                         /data1/home/mckelvin/heapoverflow
00603000-00604000 rw-p 00003000 08:02 2150398851                         /data1/home/mckelvin/heapoverflow
01263000-01284000 rw-p 00000000 00:00 0                                  [heap]
7f853f559000-7f853f6fa000 r-xp 00000000 09:01 201329536                  /lib64/libc-2.15.so
7f853f6fa000-7f853f8fa000 ---p 001a1000 09:01 201329536                  /lib64/libc-2.15.so
7f853f8fa000-7f853f8fe000 r--p 001a1000 09:01 201329536                  /lib64/libc-2.15.so
7f853f8fe000-7f853f900000 rw-p 001a5000 09:01 201329536                  /lib64/libc-2.15.so
7f853f900000-7f853f904000 rw-p 00000000 00:00 0
7f853f904000-7f853f919000 r-xp 00000000 09:01 74726670                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libgcc_s.so.1
7f853f919000-7f853fb19000 ---p 00015000 09:01 74726670                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libgcc_s.so.1
7f853fb19000-7f853fb1a000 r--p 00015000 09:01 74726670                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libgcc_s.so.1
7f853fb1a000-7f853fb1b000 rw-p 00016000 09:01 74726670                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libgcc_s.so.1
7f853fb1b000-7f853fc11000 r-xp 00000000 09:01 201329538                  /lib64/libm-2.15.so
7f853fc11000-7f853fe10000 ---p 000f6000 09:01 201329538                  /lib64/libm-2.15.so
7f853fe10000-7f853fe11000 r--p 000f5000 09:01 201329538                  /lib64/libm-2.15.so
7f853fe11000-7f853fe12000 rw-p 000f6000 09:01 201329538                  /lib64/libm-2.15.so
7f853fe12000-7f853fefc000 r-xp 00000000 09:01 74726678                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libstdc++.so.6.0.18
7f853fefc000-7f85400fb000 ---p 000ea000 09:01 74726678                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libstdc++.so.6.0.18
7f85400fb000-7f8540103000 r--p 000e9000 09:01 74726678                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libstdc++.so.6.0.18
7f8540103000-7f8540105000 rw-p 000f1000 09:01 74726678                   /usr/lib64/gcc/x86_64-pc-linux-gnu/4.8.1/libstdc++.so.6.0.18
7f8540105000-7f854011a000 rw-p 00000000 00:00 0
7f854011a000-7f854013c000 r-xp 00000000 09:01 201328977                  /lib64/ld-2.15.so
7f854031c000-7f8540321000 rw-p 00000000 00:00 0
7f8540339000-7f854033b000 rw-p 00000000 00:00 0
7f854033b000-7f854033c000 r--p 00021000 09:01 201328977                  /lib64/ld-2.15.so
7f854033c000-7f854033d000 rw-p 00022000 09:01 201328977                  /lib64/ld-2.15.so
7f854033d000-7f854033e000 rw-p 00000000 00:00 0
7fff92922000-7fff92943000 rw-p 00000000 00:00 0                          [stack]
7fff929ff000-7fff92a00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
[1]    18379 abort      ./heapoverflow

如果使用clang++(6.0 (clang-600.0.56))编译:

代码语言:javascript
复制
$  ./heapoverflow
[1]    96277 segmentation fault  ./heapoverflow

如果你认为你可能写了一个这样的bug,这里有一些提示来追踪它。

首先,使用调试标志(-g)编译代码:

代码语言:javascript
复制
g++ -g foo.cpp

然后,使用valgrind运行它

代码语言:javascript
复制
$ valgrind ./a.out
==12693== Memcheck, a memory error detector
==12693== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==12693== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==12693== Command: ./a.out
==12693==
==12693== Invalid write of size 4
==12693==    at 0x400A25: main (foo.cpp:11)
==12693==  Address 0x5a1c058 is 12 bytes after a block of size 12 alloc'd
==12693==    at 0x4C2B800: operator new[](unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==12693==    by 0x4009F6: main (foo.cpp:8)
==12693==
==12693==
==12693== HEAP SUMMARY:
==12693==     in use at exit: 0 bytes in 0 blocks
==12693==   total heap usage: 2 allocs, 2 frees, 412 bytes allocated
==12693==
==12693== All heap blocks were freed -- no leaks are possible
==12693==
==12693== For counts of detected and suppressed errors, rerun with: -v
==12693== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

该错误位于==12693==中的0x400A25: main (foo.cpp:11)

票数 25
EN

Stack Overflow用户

发布于 2016-10-31 21:50:42

这可能是由于各种原因,人们提到了其他可能性,我添加了我的案例:

我在使用多线程(包括std::pthreadstd::thread)时遇到了这个错误,这是因为我忘记锁定一个变量,这个变量可能会同时被多个线程更改。这是一个运行时错误,在某些运行中是随机出现的,但不是全部,因为...你知道两个线程之间的意外是随机的。

在我的例子中,这个变量是一个全局std::vector,我试图在一个名为push_back()的函数中对它执行一些操作。然后我使用了一个std::mutex,再也没有得到这个错误。

可能会有一些帮助

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14897157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档