Ticket #1078 (new bug)

Opened 5 years ago

Last modified 5 years ago

Parrot goes into infinite loop when attempting to test exceptions with throws_like()

Reported by: dukeleto Owned by:
Priority: normal Milestone:
Component: testing Version: 1.6.0
Severity: high Keywords:
Cc: Language:
Patch status: Platform: all

Description

This code causes Parrot to sing the never ending story:

    throws_like(<<'CODE','blah','invalid attr')
    .sub main
        $P0 = new 'ExceptionHandler'
        set_addr $P0, _handler
        push_eh $P0
        throw $P0
    _handler:
        get_results "0", $P0
        getattribute $P5, $P0, 'foo'
    .end
CODE

I ran into this while attempting to convert the exceptions tests to PIR.

Attachments

never_ending_exception.pir Download (340 bytes) - added by dukeleto 5 years ago.
Code that puts parrot into an infinite loop
never_ending_exception.patch Download (2.3 KB) - added by NotFound 5 years ago.
patch that limits the number of invocations of an exception handler

Change History

Changed 5 years ago by dukeleto

On darwin x86, this code pegs a CPU. If I kill the code while running it under gdb I get this backtrace:

(gdb) bt 
#0  0x0037928f in Parrot_sprintf_format ()
#1  0x00338772 in Parrot_vsprintf_c ()
#2  0x0031add2 in Parrot_ex_throw_from_c_args ()
#3  0x003ec058 in Parrot_default_get_attr_str ()
#4  0x002d6d7a in Parrot_getattribute_p_p_sc ()
#5  0x00375ae1 in runops_slow_core ()
#6  0x00375078 in runops_int ()
#7  0x0033101e in runops ()
#8  0x0033118c in runops_args ()
#9  0x00331772 in Parrot_runops_fromc_args ()
#10 0x0031747a in Parrot_runcode ()
#11 0x004c32d2 in imcc_run ()
#12 0x000024fe in main ()

Another backtrace is:

(gdb) bt
#0  0x91e6a5c1 in _sigunaltstack ()
#1  0x91e382c0 in longjmp ()
#2  0x0031ae5a in Parrot_ex_throw_from_c_args ()
#3  0x003ec058 in Parrot_default_get_attr_str ()
#4  0x002d6d7a in Parrot_getattribute_p_p_sc ()
#5  0x00375ae1 in runops_slow_core ()
#6  0x00375078 in runops_int ()
#7  0x0033101e in runops ()
#8  0x0033118c in runops_args ()
#9  0x00331772 in Parrot_runops_fromc_args ()
#10 0x0031747a in Parrot_runcode ()
#11 0x004c32d2 in imcc_run ()
#12 0x000024fe in main ()

Changed 5 years ago by dukeleto

Yet another is :

(gdb) bt
#0  0x0037771e in Parrot_cx_find_handler_local ()
#1  0x0031a54d in Parrot_ex_throw_from_c ()
#2  0x0031ae5a in Parrot_ex_throw_from_c_args ()
#3  0x003ec058 in Parrot_default_get_attr_str ()
#4  0x002d6d7a in Parrot_getattribute_p_p_sc ()
#5  0x00375ae1 in runops_slow_core ()
#6  0x00375078 in runops_int ()
#7  0x0033101e in runops ()
#8  0x0033118c in runops_args ()
#9  0x00331772 in Parrot_runops_fromc_args ()
#10 0x0031747a in Parrot_runcode ()
#11 0x004c32d2 in imcc_run ()
#12 0x000024fe in main ()

Are these useful?

Changed 5 years ago by dukeleto

Code that puts parrot into an infinite loop

Changed 5 years ago by NotFound

patch that limits the number of invocations of an exception handler

Changed 5 years ago by NotFound

The problem, in this and other cases, is that an exception handler is, by design, allowed to catch the exceptions thrown by himself.

The attached patch tries a possible approach: set a limit for the number of times the exception handler can be invoked, except for exceptions of CONTROL_... types. When that limit is reached, can_handle return false, allowing the next handler in the chain to take control.

The value for the limit has been chosen arbitrarily and must be fine tuned later, if the proposal is accepted.

Changed 5 years ago by pmichaud

Note that the original code itself has a bug -- after catching the exception, it doesn't remove the exception handler with pop_eh. Thus the fetch for the non-existent attribute re-triggers the top exception handler.

I would personally prefer that we find a way to treat this the same as other "recursion limit" code. I'm opposed to keeping a counter in the exception handler itself, because a single handler really ought to be able to handle an infinite number of (non-recursive) exceptions thrown to it.

(Summary: I vote against the patch and hope for something better.)

Pm

Note: See TracTickets for help on using tickets.