代码之家  ›  专栏  ›  技术社区  ›  Tilo Prütz

ruby/glibc coredump(双重自由或腐败)

  •  4
  • Tilo Prütz  · 技术社区  · 16 年前

    我正在使用一个分布式连续集成工具,这是我自己用Ruby编写的。它使用迈克·佩厄姆的《政治学》中的一个分支来分配任务。“politics”模块正在为MDN部分使用线程。

    偶尔我会遇到一个我不理解的核心垃圾堆:

    *** 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上运行,并使用“-gdbg”重建ruby和glibc,然后关闭剥离以获得有意义的核心:

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

    有没有人建议如何孤立和解决这个问题?

    4 回复  |  直到 15 年前
        1
  •  6
  •   Eric Warmenhoven    16 年前

    快速、简单,但没有那么有帮助: export MALLOC_CHECK_=2 . 这会导致glibc在 free() ,以避免堆损坏。它将 abort() 一旦检测到腐败,就立即给出一个核心转储文件,而不是等到腐败造成了实际问题。

    不是很快和容易,但更有用(如果你让它工作的话): valgrind .

        2
  •  2
  •   mark4o    16 年前

    Valgrind 使查找堆损坏问题变得容易。在Valgrind下使用Ruby1.8时报告了一些错误,但是可以使用 this ruby patch (和配置--启用valgrind)或使用 valgrind suppression file .要在valgrind下运行ruby程序,只需在命令前面加上 valgrind :

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

    如果崩溃进程是正在运行的进程的子进程,请使用 valgrind --trace-children=yes . 特别注意 无效的写入 ,这是堆损坏的迹象。

        3
  •  1
  •   Kaiwan Billimoria    15 年前

    我在一个名为rd_test的简单“c”程序中得到了同样的错误;它将使用read(2)从给定的输入文件(可能是设备文件)中读取给定数量的字节。

    这个 实际的 结果发现bug是一个1字节的缓冲区溢出(正如我所做的那样 …… Buf[n]=‘0’; … 其中“n”是读取缓冲区“buf”)的字节数。 傻我。

    但是,问题是,我从来没有抓住它,直到我运行它与瓦尔Grind! 所以我觉得瓦格林绝对值得在这样的案子上运行。

    “双重自由或腐败”的错误在我摆脱了令人讨厌的错误之后就消失了。

        4
  •  0
  •   Eric Stockman    15 年前

    我收到了同样的错误消息,不是在Ruby中,而是在Zenity程序中。 我发现它和我关上两次管子有点关系! 检查是否不释放同一堆内存的两倍或更多倍,再次关闭已关闭的文件或管道。 古德拉克

    推荐文章