[perl #59778] Rakudo Recursive Exception Throwing

Will Coleda via RT parrotbug-followup at parrotcode.org
Sun Nov 1 17:01:19 UTC 2009


On Mon Oct 20 12:11:28 2008, pmichaud wrote:
> On Thu, Oct 09, 2008 at 11:25:24PM -0700, chromatic wrote:
> > While tracking down another bug in Rakudo, I saw this backtrace.
> Note that
> > the "Class already registered!" exception gets thrown multiple
> times.  I've
> > seen this before several times in other Rakudo backtraces since the
> > exceptions/concurrency merge.
> 
> This seems to be a generic problem with exception handling in
> Parrot itself.  Here's a short PIR program that mimics what is
> happening in PGE:
> 
>     $ cat x.pir
>     .sub 'main' :main
>         'foo'(1)
>         'foo'(2)
>         'foo'(3)
>         'foo'(4)
>         'foo'(5)
>         debug 1
>     .end
> 
> 
>     .sub 'foo'
>         .param int count
>         say count
>         push_eh end
>         $P0 = newclass 'Foo::Bar'
>         say "Foo::Bar created"
>         pop_eh
>       end:
>         .return (0)
>     .end
> 
> The first call to 'foo' creates the class, the remainder should
> trap "Class Foo::Bar already register" exceptions that are
> caught by the push_eh.  However, those exceptions never disappear
> from the backtrace, as illustrated through gdb (using the
> C<debug> opcode here as a breakpoint):

This PIR is better written as:

.sub 'main' :main
    'foo'(1)
    'foo'(2)
    'foo'(3)
    'foo'(4)
    'foo'(5)
    debug 1
.end


.sub 'foo'
    .param int count
    say count
    push_eh end
        $P0 = newclass 'Foo::Bar'
        say "Foo::Bar created"
    end:
    pop_eh
  .return (0)
.end


note the transposition of the end label and the pop_eh

Run this way, using the breakpoint at the debug opcode, we get the following bt:

(gdb) bt
#0  Parrot_debug_ic (cur_opcode=0x9b13d0, interp=0x8a0080) at src/ops/core.ops:929
#1  0x00007f9d60bac3d4 in runops_slow_core (interp=0x8a0080, runcore=<value optimized 
out>, pc=0x9b13d0) at src/runcore/cores.c:844
#2  0x00007f9d60bab3e1 in runops_int (interp=0x8a0080, offset=65) at 
src/runcore/main.c:546
#3  0x00007f9d60b846d1 in runops (interp=0x8a0080, offs=<value optimized out>) at 
src/call/ops.c:97
#4  0x00007f9d60b7ed3a in Parrot_pcc_invoke_from_sig_object (interp=0x8a0080, 
sub_obj=<value optimized out>, 
    call_object=<value optimized out>) at src/call/pcc.c:296
#5  0x00007f9d60b7ee44 in Parrot_pcc_invoke_sub_from_c_args (interp=0x8a0080, 
sub_obj=0x940b30, sig=<value optimized out>)
    at src/call/pcc.c:74
#6  0x00007f9d60c8e33a in imcc_run (interp=0x8a0080, sourcefile=0x7fff6914b9d2 
"foo.pir", argc=1, argv=0x7fff6914a920)
    at compilers/imcc/main.c:793
#7  0x0000000000400b82 in main (argc=1, argv=0x7fff6914a920) at src/main.c:60

The pop_eh has to be invoked whether or not the exception occurs, otherwise it will hang 
around. I think this behavior changed some time ago, but is now expected.

Resolving this ticket; Please open any new or related issues at https://trac.parrot.org/

> $ gdb parrot
> GNU gdb 6.8-debian
> Copyright (C) 2008 Free Software Foundation, Inc.
> (gdb) b Parrot_debug_ic
> Function "Parrot_debug_ic" not defined.
> Make breakpoint pending on future shared library load? (y or [n]) y
> Breakpoint 1 (Parrot_debug_ic) pending.
> (gdb) run x.pir
> Starting program: /home/pmichaud/parrot/trunk/parrot x.pir
> [Thread debugging using libthread_db enabled]
> 1
> Foo::Bar created
> 2
> 3
> 4
> 5
> [New Thread 0xb766b6c0 (LWP 25876)]
> [Switching to Thread 0xb766b6c0 (LWP 25876)]
> 
> Breakpoint 1, Parrot_debug_ic (cur_opcode=0x811cc70, interp=0x804f040)
>     at src/ops/core.ops:932
> 932         if ($1 != 0) { Interp_debug_SET(interp,   $1); }
> (gdb) bt
> #0  Parrot_debug_ic (cur_opcode=0x811cc70, interp=0x804f040)
>     at src/ops/core.ops:932
> #1  0xb7ba755c in runops_slow_core (interp=0x804f040, pc=0x811cc70)
>     at src/runops_cores.c:222
> #2  0xb7b78fa9 in runops_int (interp=0x804f040, offset=66)
>     at src/interpreter.c:937
> #3  0xb7b79883 in runops (interp=0x804f040, offs=66) at
> src/inter_run.c:101
> #4  0xb7b79b4f in runops_args (interp=0x804f040, sub=0x80e86e4,
> obj=0x80b1058,
>     meth_unused=0x0, sig=0xb7e47cb8 "vP",
>     ap=0xbffd264c
> "\224\205\016\bp���\224�\020\b\210&��(\035��@�
\004\b\224\205\016\b��\017\b\024")
> at src/inter_run.c:236
> #5  0xb7b79c9c in Parrot_runops_fromc_args (interp=0x804f040,
> sub=0x80e86e4,
>     sig=0xb7e47cb8 "vP") at src/inter_run.c:300
> #6  0xb7b622c7 in Parrot_ex_throw_from_c (interp=0x804f040,
>     exception=0x80e8594) at src/exceptions.c:291
> #7  0xb7b6239e in Parrot_ex_throw_from_c_args (interp=0x804f040,
> ret_addr=0x0,
>     exitcode=20, format=0xb7e4afa0 "Class %Ss already registered!\n")
>     at src/exceptions.c:338
> #8  0xb7b9b13a in fail_if_type_exists (interp=0x804f040,
> name=0x80e86ac)
>     at src/oo.c:556
> #9  0xb7b9b1a4 in Parrot_oo_register_type (interp=0x804f040,
> name=0x80e86ac)
>     at src/oo.c:587
> #10 0xb7d7d8aa in init_class_from_hash (interp=0x804f040,
> self=0x80e8690,
>     info=0x80e85b0) at ./src/pmc/class.pmc:222
> #11 0xb7d7f338 in Parrot_Class_init_pmc (interp=0x804f040,
> pmc=0x80e8690,
>     init_data=0x80e86ac) at ./src/pmc/class.pmc:512
> #12 0xb7ba6b41 in pmc_new_init (interp=0x804f040, base_type=50,
> init=0x80e86ac)
>     at src/pmc.c:368
> #13 0xb7b105a3 in Parrot_newclass_p_sc (cur_opcode=0x811cc98,
> interp=0x804f040)
>     at src/ops/object.ops:242
> #14 0xb7ba755c in runops_slow_core (interp=0x804f040, pc=0x811cc98)
>     at src/runops_cores.c:222
> #15 0xb7b78fa9 in runops_int (interp=0x804f040, offset=66)
>     at src/interpreter.c:937
> #16 0xb7b79883 in runops (interp=0x804f040, offs=66) at
> src/inter_run.c:101
> #17 0xb7b79b4f in runops_args (interp=0x804f040, sub=0x80e8a10,
> obj=0x80b1058,
>     meth_unused=0x0, sig=0xb7e47cb8 "vP",
>     ap=0xbffd29bc
> "�\210\016\bp�𷤲\021\b�)��(\035��@�\004\b�\210\016\b��\017\b\024") at
> src/inter_run.c:236
> #18 0xb7b79c9c in Parrot_runops_fromc_args (interp=0x804f040,
> sub=0x80e8a10,
>     sig=0xb7e47cb8 "vP") at src/inter_run.c:300
> #19 0xb7b622c7 in Parrot_ex_throw_from_c (interp=0x804f040,
>     exception=0x80e88c0) at src/exceptions.c:291
> #20 0xb7b6239e in Parrot_ex_throw_from_c_args (interp=0x804f040,
> ret_addr=0x0,
>     exitcode=20, format=0xb7e4afa0 "Class %Ss already registered!\n")
>     at src/exceptions.c:338
> #21 0xb7b9b13a in fail_if_type_exists (interp=0x804f040,
> name=0x80e89d8)
>     at src/oo.c:556
> #22 0xb7b9b1a4 in Parrot_oo_register_type (interp=0x804f040,
> name=0x80e89d8)
>     at src/oo.c:587
> #23 0xb7d7d8aa in init_class_from_hash (interp=0x804f040,
> self=0x80e89bc,
>     info=0x80e88dc) at ./src/pmc/class.pmc:222
> #24 0xb7d7f338 in Parrot_Class_init_pmc (interp=0x804f040,
> pmc=0x80e89bc,
>     init_data=0x80e89d8) at ./src/pmc/class.pmc:512
> #25 0xb7ba6b41 in pmc_new_init (interp=0x804f040, base_type=50,
> init=0x80e89d8)
>     at src/pmc.c:368
> #26 0xb7b105a3 in Parrot_newclass_p_sc (cur_opcode=0x811cc98,
> interp=0x804f040)
>     at src/ops/object.ops:242
> #27 0xb7ba755c in runops_slow_core (interp=0x804f040, pc=0x811cc98)
>     at src/runops_cores.c:222
> #28 0xb7b78fa9 in runops_int (interp=0x804f040, offset=66)
>     at src/interpreter.c:937
> #29 0xb7b79883 in runops (interp=0x804f040, offs=66) at
> src/inter_run.c:101
> #30 0xb7b79b4f in runops_args (interp=0x804f040, sub=0x80e8d3c,
> obj=0x80b1058,
>     meth_unused=0x0, sig=0xb7e47cb8 "vP",
>     ap=0xbffd2d2c "�\213\016\bp�����\021\bh-
> ��(\035��@�\004\b�\213\016\b\204�\017\b\024") at src/inter_run.c:236
> #31 0xb7b79c9c in Parrot_runops_fromc_args (interp=0x804f040,
> sub=0x80e8d3c,
>     sig=0xb7e47cb8 "vP") at src/inter_run.c:300
> #32 0xb7b622c7 in Parrot_ex_throw_from_c (interp=0x804f040,
>     exception=0x80e8bec) at src/exceptions.c:291
> #33 0xb7b6239e in Parrot_ex_throw_from_c_args (interp=0x804f040,
> ret_addr=0x0,
>     exitcode=20, format=0xb7e4afa0 "Class %Ss already registered!\n")
>     at src/exceptions.c:338
> #34 0xb7b9b13a in fail_if_type_exists (interp=0x804f040,
> name=0x80e8d04)
>     at src/oo.c:556
> #35 0xb7b9b1a4 in Parrot_oo_register_type (interp=0x804f040,
> name=0x80e8d04)
>     at src/oo.c:587
> #36 0xb7d7d8aa in init_class_from_hash (interp=0x804f040,
> self=0x80e8ce8,
>     info=0x80e8c08) at ./src/pmc/class.pmc:222
> #37 0xb7d7f338 in Parrot_Class_init_pmc (interp=0x804f040,
> pmc=0x80e8ce8,
>     init_data=0x80e8d04) at ./src/pmc/class.pmc:512
> #38 0xb7ba6b41 in pmc_new_init (interp=0x804f040, base_type=50,
> init=0x80e8d04)
>     at src/pmc.c:368
> #39 0xb7b105a3 in Parrot_newclass_p_sc (cur_opcode=0x811cc98,
> interp=0x804f040)
>     at src/ops/object.ops:242
> #40 0xb7ba755c in runops_slow_core (interp=0x804f040, pc=0x811cc98)
>     at src/runops_cores.c:222
> #41 0xb7b78fa9 in runops_int (interp=0x804f040, offset=66)
>     at src/interpreter.c:937
> #42 0xb7b79883 in runops (interp=0x804f040, offs=66) at
> src/inter_run.c:101
> #43 0xb7b79b4f in runops_args (interp=0x804f040, sub=0x80e9068,
> obj=0x80b1058,
>     meth_unused=0x0, sig=0xb7e47cb8 "vP", ap=0xbffd309c
> "\030\217\016\bn6")
>     at src/inter_run.c:236
> #44 0xb7b79c9c in Parrot_runops_fromc_args (interp=0x804f040,
> sub=0x80e9068,
>     sig=0xb7e47cb8 "vP") at src/inter_run.c:300
> #45 0xb7b622c7 in Parrot_ex_throw_from_c (interp=0x804f040,
>     exception=0x80e8f18) at src/exceptions.c:291
> #46 0xb7b6239e in Parrot_ex_throw_from_c_args (interp=0x804f040,
> ret_addr=0x0,
>     exitcode=20, format=0xb7e4afa0 "Class %Ss already registered!\n")
>     at src/exceptions.c:338
> #47 0xb7b9b13a in fail_if_type_exists (interp=0x804f040,
> name=0x80e9030)
>     at src/oo.c:556
> #48 0xb7b9b1a4 in Parrot_oo_register_type (interp=0x804f040,
> name=0x80e9030)
>     at src/oo.c:587
> #49 0xb7d7d8aa in init_class_from_hash (interp=0x804f040,
> self=0x80e9014,
>     info=0x80e8f34) at ./src/pmc/class.pmc:222
> #50 0xb7d7f338 in Parrot_Class_init_pmc (interp=0x804f040,
> pmc=0x80e9014,
>     init_data=0x80e9030) at ./src/pmc/class.pmc:512
> #51 0xb7ba6b41 in pmc_new_init (interp=0x804f040, base_type=50,
> init=0x80e9030)
>     at src/pmc.c:368
> #52 0xb7b105a3 in Parrot_newclass_p_sc (cur_opcode=0x811cc98,
> interp=0x804f040)
>     at src/ops/object.ops:242
> #53 0xb7ba755c in runops_slow_core (interp=0x804f040, pc=0x811cc98)
>     at src/runops_cores.c:222
> #54 0xb7b78fa9 in runops_int (interp=0x804f040, offset=0)
>     at src/interpreter.c:937
> #55 0xb7b79883 in runops (interp=0x804f040, offs=0) at
> src/inter_run.c:101
> #56 0xb7b79b4f in runops_args (interp=0x804f040, sub=0x80e9538,
> obj=0x80b1058,
>     meth_unused=0x0, sig=0xb7e47977 "vP", ap=0xbffd340c "")
>     at src/inter_run.c:236
> #57 0xb7b79c9c in Parrot_runops_fromc_args (interp=0x804f040,
> sub=0x80e9538,
>     sig=0xb7e47977 "vP") at src/inter_run.c:300
> #58 0xb7b5f8f7 in Parrot_runcode (interp=0x804f040, argc=1,
> argv=0xbffd3578)
>     at src/embed.c:959
> #59 0xb7e21aa2 in imcc_run_pbc (interp=0x804f040, obj_file=0,
> output_file=0x0,
>     argc=1, argv=0xbffd3578) at compilers/imcc/main.c:791
> #60 0xb7e224c2 in imcc_run (interp=0x804f040, sourcefile=0xbffd46ff
> "x.pir",
>     argc=1, argv=0xbffd3578) at compilers/imcc/main.c:1079
> #61 0x08048938 in main (argc=1, argv=0xbffd3578) at src/main.c:61
> (gdb)
> 
> 
> If there's something I need to add to the PIR code to properly
> trap and handle the exception, or if this particular pattern for
> handling exceptions isn't intended to work this way, let me know.
> 
> We can also now fix PGE and other tools to work around this issue
> by avoiding calls to newclass for existing classes, but there still
> seems something odd about exception handling here.
> 
> Hope this helps,
> 
> Pm
> 


-- 
Will "Coke" Coleda


More information about the parrot-dev mailing list