Frage

Ich bin mit einem verteilten kontinuierlichen Integrations-Tool, das ich von mir selbst in Ruby geschrieben. Es verwendet eine Gabel von Mike Perham der „Politik“ für die Verteilung der Aufgaben. Die „Politik“ Modul Threads für den mDNS Teil verwendet wird.

Immer wieder begegne ich einen Core-Dump, die ich nicht verstehe:

*** 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: ========
...

ich auf Gentoo leite und habe wieder aufzubauen Ruby und Glibc mit „-gdbg“ und aus dem Striping drehte einen sinnvollen Kern zu erhalten:

...
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) 

Hmm ??? Für mich sieht wie folgt aus, es ist völlig Ruby-intern. Auf anderen „double frei oder Korruption“ Probleme hier bei Stackoverflow ich gesehen habe, dass vielleicht Fäden Teil des Problems sind.

Auch das Problem tritt nicht an der genau gleichen Position. Ich habe eine andere Backtrace, die viel länger ist, aber der Absturz ist auch in garbage_collect aber mit einem etwas anderen Weg:

(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.)

Hat jemand einen Vorschlag, wie man isoliert und vielleicht dieses Problem lösen?

War es hilfreich?

Lösung

Schnell, einfach und nicht als hilfreich: export MALLOC_CHECK_=2. Diese Ursachen glibc einige zusätzliche Ebene zu tun, während free() des Prüfens, Heapbeschädigung zu vermeiden. Es wird abort() und einen Core-Dump geben, sobald es Korruption erkennt, anstatt zu warten, bis es ein tatsächliches Problem der Korruption verursacht wird.

Nicht ganz so schnell und einfach, aber viel hilfreicher (wenn Sie es in Betrieb). valgrind

Andere Tipps

Valgrind macht es einfach Heapbeschädigung Probleme zu finden. Es gibt einige störende Fehler gemeldet, wenn Ruby 1.8 unter valgrind verwenden, aber sie können mit beseitigt werden dieser rubin Patch (und Konfiguration mit --enable-valgrind) oder ein valgrind Unterdrückung Datei . Um Ihre Ruby-Programm unter valgrind zu laufen, das Präfix nur den Befehl mit valgrind:

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

Wenn der Absturz-Prozess ist ein Kind des Prozesses Sie ausführen, verwenden valgrind --trace-children=yes. Schauen Sie insbesondere für ungültig schreibt , die ein Zeichen für Heapbeschädigung sind.

Ich habe diese sehr gleichen Fehler in einem einfachen ‚C‘ Programm namens rd_test; es wäre nur eine bestimmte Anzahl von Bytes, die mit Lese (2) aus einer gegebenen Eingabedatei gelesen (könnte eine Gerätedatei sein).

Die eigentliche drehten Fehler aus einem Pufferüberlauf von 1 Byte sein (so wie ich     ...     buf [n] = '\ 0';     ... wobei ‚n‘ die Anzahl von Bytes in den Puffer ‚buf‘ lesen). Dumme mich.

Aber die Sache, die ich nie gefangen, bis ich lief es mit valgrind! Also IMHO valgrind lohnt Laufen auf Fälle wie diesen.

Die ‚doppelte frei oder Korruption‘ Fehler gingen so schnell weg, wie ich von den säumigen Fehlern losgeworden.

Ich habe die gleiche Fehlermeldung, nicht in Ruby, aber in einem zenity-Programm. Ich entdeckte es etwas todo hatte bei mir zwei mal ein offenes Rohr zu schließen! Überprüfen Sie, ob Sie kostenlos zwei-oder mehrmals den gleichen Heap-Speicher nicht, schließen bereits wieder geschlossen Dateien oder Pipes. Goodluck

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top