Baru-baru ini saya mendapatkan kesalahan berikut dari PHP saya:
WARNING: [pool www] child 42475 said into stderr: "*** glibc detected *** php-fpm: pool www: corrupted double-linked list: 0x00000000013fe680 ***"
Saya tidak terlalu terganggu dengan masalah ini, dan tidak terlalu tertarik untuk memperbaikinya. Tetapi saya sangat tertarik untuk memahami apa arti sebenarnya dari error ini, karena saya belum pernah melihatnya sebelumnya. Saya yakin tahu apa itu daftar double-linked, tetapi saya gagal membuat program yang memicu kesalahan ini.
Bisakah seseorang memberikan saya potongan kode singkat yang menyebabkan glibc mengatakan ' daftar double-linked yang rusak ' ketika saya mengkompilasi dan mengeksekusinya?
Saya sendiri telah menemukan jawaban atas pertanyaan saya:)
Jadi apa yang saya tidak mengerti adalah bagaimana glibc dapat membedakan antara Segfault dan daftar double-linked yang rusak, karena menurut pemahaman saya, dari perspektif glibc mereka harus terlihat seperti hal yang sama. Karena jika saya mengimplementasikan double-linked list di dalam program saya, bagaimana mungkin glibc bisa tahu bahwa ini adalah double-linked list, bukannya struct lainnya? Mungkin tidak bisa, jadi itulah mengapa saya bingung.
Sekarang saya telah melihat malloc/malloc.c di dalam kode glibc, dan saya melihat yang berikut ini:
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; \
Jadi sekarang ini tiba-tiba masuk akal. Alasan mengapa glibc dapat mengetahui bahwa ini adalah daftar ganda adalah karena daftar tersebut adalah bagian dari glibc itu sendiri. Saya bingung karena saya pikir glibc entah bagaimana dapat mendeteksi bahwa beberapa pemrograman sedang membangun daftar double-linked, yang saya tidak mengerti bagaimana cara kerjanya. Tetapi jika daftar double-linked yang dibicarakan ini adalah bagian dari glibc itu sendiri, tentu saja glibc dapat mengetahuinya sebagai daftar double-linked.
Saya masih belum tahu apa yang memicu kesalahan ini. Tapi setidaknya saya mengerti perbedaan antara daftar double-linked yang rusak dan Segfault, dan bagaimana glibc bisa tahu bahwa struct ini seharusnya adalah daftar double-linked:)
Bagi siapa saja yang mencari solusi di sini, saya memiliki masalah serupa dengan C++: malloc(): smallbin double linked list rusak:
Hal ini disebabkan oleh fungsi yang tidak mengembalikan nilai yang seharusnya.
std::vector<Object> generateStuff(std::vector<Object>& target> {
std::vector<Object> returnValue;
editStuff(target);
// RETURN MISSING
}
Tidak tahu mengapa ini bisa dikompilasi. Mungkin ada peringatan tentang hal itu.
Saya mengalami kesalahan ini dalam beberapa kode di mana seseorang memanggil exit() dalam satu thread pada saat yang sama dengan kembalinya main()
, sehingga semua konstruktor global/statis ditendang dalam dua thread yang terpisah secara bersamaan.
Kesalahan ini juga bermanifestasi sebagai double free atau corruption
, atau segfault/sig11 di dalam exit()
atau di dalam malloc_consolidate
, dan kemungkinan lainnya. Tumpukan panggilan untuk kerusakan malloc_consolidate dapat menyerupai:
#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[] (...)
(...)
Saya tidak bisa menunjukkan masalah ini saat berjalan di bawah valgrind.