2010-02-10 307 views
4

我正在使用我自己在Ruby中編寫的分佈式持續集成工具。它使用Mike Perham的「政治」分支來分配任務。 「政治」模塊使用mDNS部分的線程。Ruby/Glibc coredump(雙重釋放或損壞)

時不時地,我遇到一個核心轉儲我不明白:

*** 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的運行,並有重建紅寶石和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) 

嗯???對我來說,這看起來完全是Ruby實習生。在其他「雙免費或腐敗」的問題在這裏在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.) 

有沒有人建議如何分離,也許解決這個問題?

+0

你在使用X86_64架構嗎? – Neel 2010-02-15 18:01:49

+0

不,軟件運行的機器是具有Gentoo的32位(x86)XEN和KVM客戶機。主機正在運行64位(x86_64)Gentoo。 – 2010-02-16 07:52:03

回答

6

快速,簡單,沒有太大的用處:export MALLOC_CHECK_=2。這會導致glibc在free()期間執行一些額外的檢查級別,以避免堆損壞。它會abort(),並在檢測到腐敗後立即給出核心轉儲,而不是等到存在由腐敗引起的實際問題。

沒有這麼方便快捷,但更有益的(如果你得到它的工作):valgrind

2

Valgrind可以很容易找到堆損壞問題。在valgrind下使用Ruby 1.8時會報告一些錯誤的錯誤,但可以使用this ruby patch(和使用--enable-valgrind配置)或使用valgrind suppression file來消除它們。要下的valgrind運行Ruby程序,只需在命令前加上valgrind

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

如果崩潰進程是正在運行的進程的子進程,使用valgrind --trace-children=yes。請特別注意無效寫入,這是堆損壞的跡象。

+0

嗨,我想了很久我會接受哪個答案。我接受了第一個,因爲它給了我valgrind參考旁邊的MALLOC_CHECK線索,因爲它是第一個。 不過,你的答案是有用的,因爲valgrind + ruby​​的細節。但是:「只能有一個」 - 我必須做出決定。 – 2010-02-18 11:44:02

0

我得到了同樣的錯誤信息,而不是在Ruby,但在zenity程序。 我發現它有一些待辦事項關閉了兩次打開的管道! 檢查是否不釋放兩次或多次相同的堆內存,再次關閉已關閉的文件或管道。 古德勒克

1

我在叫rd_test一個簡單的「C」程序這個非常相同的錯誤;它只會從給定的輸入文件(可能是設備文件)使用read(2)讀取給定數量的字節。

實際錯誤原來是1個字節的緩衝器溢出(如我沒有 ... BUF [N] = '\ 0'; ... 其中 'n' 是數的字節讀入緩衝區'buf')。 傻我。

但是,事情是我從來沒有發現,直到我用valgrind跑它! 所以恕我直言valgrind絕對值得這樣的情況下運行。

只要我擺脫了犯規錯誤,'雙免費或腐敗'的錯誤就消失了。