2013-02-15 61 views
27

が、私は最近、私のPHPから次のエラーを得ている何を意味し:「壊れた二重リンクリストは、」

WARNING: [pool www] child 42475 said into stderr: "*** glibc detected *** php-fpm: pool www: corrupted double-linked list: 0x00000000013fe680 ***" 

私は非常にこの問題に悩まされていないし、それを固定に非常に興味を持っていませんよ。 しかし、私はこれを見たことがないので、このエラーの「ダブルリンクリストが壊れています。私はダブルリンクされたリストが何であるかを知っていると思いますが、私はこのエラーを引き起こすプログラムを作りませんでした。

私がコンパイルして実行するときに、glibcに '壊れたダブルリンクリスト'が表示されるような短いコードスニペットを誰かに教えてもらえますか?

答えて

43

私自身は私の質問への答えを見つけた:)私はので、私の理解によると、から、glibcのはとSegfaultと、破損した二重リンクリストを区別できる方法だった理解していなかったものをそう

glibcの視点は同じもののように見えるはずです。 プログラム内でダブルリンクされたリストを実装すると、glibcはこれが他の構造体の代わりにダブルリンクされたリストであることをどのように知ることができますか?それはおそらくできないので、なぜ私は混乱していた。

は、今私はglibcのコードの内部のmalloc/malloc.c見てきた、と私は以下を参照してください。

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がこの構造体が二重リンクリストであることをどのように知ることができるでしょうか?

+21

は面白いだろう助けるかもしれない;) "不正プログラムの設計" - > *クラッシュ* – mlvljr

1

ここで解決策を探している人なら、 malloc():smallbin double linked list破損:

これは、想定されていた値を返さない関数が原因でした。

std::vector<Object> generateStuff(std::vector<Object>& target> { 
    std::vector<Object> returnValue; 
    editStuff(target); 
    // RETURN MISSING 
} 

これが結局コンパイルできた理由がわかりません。おそらくそれについての警告がありました。

0

main()と同じ時刻に1つのスレッドでexit()を呼び出していたコードで、このエラーが発生したため、すべてのグローバル/静的コンストラクタが2つの別々のスレッドで同時に開始されました。

このエラーは、double free or corruption、またはexit()またはmalloc_consolidateの中のsegfault/sig11などのようにも現れます。 malloc_consolidateクラッシュのためのコールスタックが似ていることがあります。

#0 0xabcdabcd in malloc_consolidate() from /lib/libc.so.6 
#1 0xabcdabcd in _int_free() from /lib/libc.so.6 
#2 0xabcdabcd in operator delete (...) 
#3 0xabcdabcd in operator delete[] (...) 
(...) 

私はvalgrindの下で実行しながら、それがこの問題を発揮することができませんでした。

13

ヒープオーバーフローcorrupted double-linked listmalloc(): memory corruptiondouble free or corruption (!prev)様glibcの警告の非難(常にではない)でなければなりません。

これは以下のコードによって再生されるべきである:G ++(4.5.4)を使用してコンパイルした場合

#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; 
} 

$ ./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-7f00 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 

と打ち鳴らす++(6.0(打ち鳴らす-600.0.56を用いてコンパイルした場合)):

$ ./heapoverflow 
[1] 96277 segmentation fault ./heapoverflow 

あなたが思っている場合あなたはそのようなバグを書いているかもしれませんが、ここでそれをトレースするためのヒントがあります。その後、

g++ -g foo.cpp 

そして、valgrindを使用して、それを実行します:

まず、デバッグフラグ(-g)でコードをコンパイル

$ 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:メイン(foo.cpp:11)

0

これは異なる理由で発生する可能性があり、一部の他の候補者と私は紹介します

マルチスレッド(両方ともstd::pthreadstd::thread)を使用しているときにこのエラーが発生し、マルチスレッドが同時に変更する可能性のある変数をロックするのを忘れてエラーが発生しました。 このエラーはいくつかの実行ではランダムに発生しますが、すべてではありません。

私の場合は、変数iがスレッドによって呼び出される関数で、その中にpush_back()何か..しようとしましたが、その後、私はstd::mutexを使用して、再度このエラーを得たことはありませんグローバルstd::vectorれたこと。

glibsは、そのスマートだった場合、いくつかの

関連する問題