سؤال

أنا أستخدم أداة التكامل المستمر الموزعة التي كتبتها بنفسي في روبي. ويستخدم شوكة من "سياسة" مايك بيرهام لتوزيع المهام. وحدة "السياسة" تستخدم المواضيع لجزء MDNS.

كل الآن وتواجه تفريغ أساسي لا أفهمه:

*** glibc detected *** ruby: double free or corruption (fasttop): 0x086d8600 ***
======= Backtrace: =========
/lib/libc.so.6[0xb7cef494]
/lib/libc.so.6[0xb7cf0b93]
/lib/libc.so.6(cfree+0x6d)[0xb7cf3c7d]
/usr/lib/libruby18.so.1.8[0xb7e8adf8]
/usr/lib/libruby18.so.1.8(ruby_xmalloc+0x85)[0xb7e8b395]
/usr/lib/libruby18.so.1.8[0xb7e5065e]
...
/usr/lib/libruby18.so.1.8[0xb7e717f4]
/usr/lib/libruby18.so.1.8[0xb7e74296]
/usr/lib/libruby18.so.1.8(rb_yield+0x27)[0xb7e7fb57]
======= Memory map: ========
...

أنا أركض في Gentoo وإعادة بناء Ruby و Glibc مع "-gdbg" وإيقاف تشغيل الشريط للحصول على جوهر مفيد:

...
Core was generated by `ruby /home/develop/dcc/bin/dcc-worker'.
Program terminated with signal 6, Aborted.
#0  0xb7f20410 in __kernel_vsyscall ()
(gdb) bt
#0  0xb7f20410 in __kernel_vsyscall ()
#1  0xb7cacb60 in *__GI___open_catalog (cat_name=0x6 <Address 0x6 out of bounds>, nlspath=0xbf9d6f00 " ", env_var=0x0, catalog=0x1) at open_catalog.c:237
#2  0xb7cae498 in __sigdelset (set=0x6) from /lib/libc.so.6
#3  *__GI_sigfillset (set=0x6) at ../signal/sigfillset.c:42
#4  0xb7ce952d in freopen64 (filename=0x2 <Address 0x2 out of bounds>, mode=0xb7db02c8 "\" total=\"%zu\" count=\"%zu\"/>\n", fp=0x9) at freopen64.c:47
#5  0xb7cef494 in _IO_str_init_readonly (sf=0x86d8600, ptr=0xb7eef5a9 "te\213V\b\205\322\017\204\220", size=-1210273804) at strops.c:88
#6  0xb7cf0b93 in mALLINFo (av=0xb) at malloc.c:5865
#7  0xb7cf3c7d in __libc_calloc (n=141395456, elem_size=3214793136) at malloc.c:4019
#8  0xb7e8adf8 in ?? () at gc.c:1390 from /usr/lib/libruby18.so.1.8
#9  0x086d8600 in ?? ()
#10 0xb7e89400 in rb_gc_disable () at gc.c:256
#11 0xb7e8b395 in add_freelist () at gc.c:1087
#12 gc_sweep () at gc.c:1186
#13 garbage_collect () at gc.c:1524
#14 0xb7e5065e in ?? () from /usr/lib/libruby18.so.1.8
#15 0x00000340 in ?? ()
#16 0x00000000 in ?? ()
(gdb) 

همم؟؟؟ بالنسبة لي هذا يبدو وكأنه متدرب روبي تماما. على مشاكل "مزدوجة الحرة أو الفساد المزدوجة" هنا في Stackoverflow لقد رأيت أن المواضيع ربما هي جزء من المشكلة.

كما لا تحدث المشكلة في نفس الموقف بالضبط. لدي بركة بريدية أخرى وهي أطول بكثير ولكن الحادث هو أيضا garbage_collect ولكن مع مسار مختلف قليلا:

(gdb) bt
#0  0xffffe430 in __kernel_vsyscall ()
#1  0xf7c8b8c0 in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#2  0xf7c8d1f5 in *__GI_abort () at abort.c:88
#3  0xf7cc7e35 in __libc_message (do_abort=2, fmt=0xf7d8daa8 "*** glibc detected *** %s: %s: 0x%s ***\n") at ../sysdeps/unix/sysv/linux/libc_fatal.c:170
#4  0xf7ccdd24 in malloc_printerr (action=2, str=0xf7d8dbec "double free or corruption (fasttop)", ptr=0x911f5d0) at malloc.c:6197
#5  0xf7ccf403 in _int_free (av=0xf7daa380, p=0x911f5c8) at malloc.c:4750
#6  0xf7cd24ad in *__GI___libc_free (mem=0x911f5d0) at malloc.c:3716
#7  0xf7e68768 in obj_free () at gc.c:1366
#8  gc_sweep () at gc.c:1174
#9  garbage_collect () at gc.c:1524
#10 0xf7e68be5 in rb_newobj () at gc.c:436
#11 0xf7eb9840 in str_alloc (klass=0) at string.c:67
... (150 lines of rb_eval/call/yield etc.)

لديه أي شخص اقتراح كيفية عزل وربما حل هذه المشكلة؟

هل كانت مفيدة؟

المحلول

سريع، سهل، وليس مفيدة: export MALLOC_CHECK_=2. وبعد هذا يسبب Glibc للقيام ببعض مستوى إضافي من التدقيق أثناء free(), ، لتجنب فساد الكومة. سوف تكون abort() وإعطاء تفريغ أساسي بمجرد اكتشاف الفساد، بدلا من الانتظار حتى توجد مشكلة فعلية ناتجة عن الفساد.

ليس تماما بسرعة وسهولة، ولكن أكثر فائدة (إذا كنت تعمل): valgrind..

نصائح أخرى

valgrind. يجعل من السهل العثور على مشاكل الفساد الكومة. هناك بعض الأخطاء الزائفة التي تم الإبلاغ عنها عند استخدام Ruby 1.8 تحت Valgrind، ولكن يمكن القضاء عليها باستخدام هذا روبي التصحيح (وتكوين مع Valgrind) أو باستخدام فيرجريند قمع الملفات. وبعد لتشغيل برنامج Ruby الخاص بك تحت Valgrind، فقط بادئة الأمر مع valgrind:

valgrind ruby /home/develop/dcc/bin/dcc-worker

إذا كانت عملية التحول هي طفل من العملية التي تقوم بتشغيلها، فاستخدمها valgrind --trace-children=yes. وبعد انظروا بشكل خاص ل يكتب غير صالح, وهي علامة على الفساد الكومة.

حصلت على نفس الخطأ هذا في برنامج "C" بسيط يسمى RD_Test؛ سوف يقرأ مجرد عدد معين من البايتات باستخدام القراءة (2) من ملف إدخال معين (قد يكون ملف جهاز).

ال فعلي تحول الخلل إلى أن يكون تجاوزا مؤقتا من 1 بايت (كما فعلت ... BUF [N] = ' 0'؛ ... حيث "n" هو عدد البايتات التي يقرأها في المخزن المؤقت "BUF"). ما أغباني.

ولكن، فإن الشيء لم أكن أخوضه أبدا حتى ركضت مع Valgrind! لذلك فإن فالجريند IMHO يستحق بالتأكيد تشغيل في حالات مثل هذا.

ذهب خطأ "مزدوج الحر أو الفساد" بعيدا بمجرد التخلص من الخطأ المخالف.

حصلت على نفس رسالة الخطأ، وليس في Ruby ولكن في برنامج مرتاحي. لقد اكتشفت أنه كان لدي شيء تودو معي إغلاق مرتين أنبوب مفتوح! تحقق مما إذا كنت لا تحرر مرة واحدة من نفس الذاكرة الهوائية، إغلاق الملفات أو الأنابيب المغلقة مرة أخرى بالفعل. حظ سعيد

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top