Blog

autoboxをデバッグしたときのメモ

my $X;

END { $X->() }

use autobox;

$X = sub { 1->OMG() };

みたいなコードがしぬのが知られていて、だいぶ前に report したんだけどぜんぜん対応されなくて、苦慮していたのだが。。

gdb でbacktrace をみてみたところ、こんなかんじになっていた。

Starting program: /home/tokuhirom/.plenv/versions/5.17.8/bin/perl -Mblib hoge.pl

Program received signal SIGSEGV, Segmentation fault.
PTABLE_find (key=0x8b57f8, tbl=<optimized out>) at ptable.h:81
81          tblent = tbl->tbl_ary[hash & tbl->tbl_max];
gdb$ bt #0  PTABLE_find (key=0x8b57f8, tbl=<optimized out>) at ptable.h:81
#1  PTABLE_fetch (key=0x8b57f8, tbl=0x0) at ptable.h:92
#2  autobox_method_common (meth=0x9dccc0, hashp=0x7fffffffdcdc) at autobox.xs:236 #3  0x00007ffff64ef137 in autobox_method_named () at autobox.xs:131
#4  0x00000000004b7e8b in Perl_runops_debug () at dump.c:2192
#5  0x000000000043cd39 in Perl_call_sv (sv=0x89c858, flags=13) at perl.c:2722
#6  0x000000000043fada in Perl_call_list (oldscope=1, paramList=0x960700) at perl.c:4818
#7  0x00000000004409b5 in perl_destruct (my_perl=<optimized out>) at perl.c:558
#8  0x000000000041df54 in main (argc=3, argv=0x7fffffffe248, env=0x7fffffffe268) at perlmain.c:125

で、調べてみたら、PTABLE_free ってのを END でよんでいることが判明。

void
END()
    PROTOTYPE:
    CODE:
        if (autobox_old_ck_subr) { /* make sure we got as far as initializing it */
            PL_check[OP_ENTERSUB] = autobox_old_ck_subr;
        }

        PTABLE_free(AUTOBOX_OP_MAP);
        AUTOBOX_OP_MAP = NULL;

There is no reason to free explicitly, since OS will free it. だよねーということで、PTABLE_free しなくていいよねというパッチをおくりつけた。

https://rt.cpan.org/Ticket/Display.html?id=80400&results=fef84c05b2dfcb45fbb990e2be29ce07