Ticket #833 (closed bug: fixed)

Opened 5 years ago

Last modified 4 years ago

Exception from :init sub in PIR compreg causes problems

Reported by: whiteknight Owned by: whiteknight
Priority: major Milestone:
Component: core Version: 1.3.0
Severity: medium Keywords: inferior runloop
Cc: Language:
Patch status: Platform: all

Description

Actually, this is just one more example of the inferior runloops problem, although pmichaud++ has been able to narrow it down to a pure-PIR test case:

.sub main
    $S0 = <<'END'
        .sub 'abc' :load :init
            say 'run abc'
        .end

        .sub 'def' :load :init
            die 'died in def'
        .end

        .sub 'ghi' :load :init
            say 'run ghi'
        .end

        .sub 'main' :main
            say 'run main'
        .end
END

    $P0 = compreg 'PIR'

    push_eh trap1
    $P0($S0)
  trap1:
    pop_eh


    push_eh trap2
    $P0($S0)
  trap2:
    pop_eh
.end

What happens, in a nutshell, is this: The :init functions from the compiled code string are executed immediately in an child runloop. function 'def' throws an exception which is handled by a handler from outside the compiled code string. Execution continues in the child runloop until the end of the program. Once that terminates, the C stack is unwound back up to the parent runloop and execution continues, but now with a corrupted context.

This isn't just a problem with IMCC, although the problem does manifest inside IMCC in this case. It's a problem any time we mix child runloops with exceptions.

We now know what causes this problem, and there are a handful of examples of manifestations of it throughout the Trac and RT ticket queues by various names. Resolving this issue won't be difficult if we can agree on a sane way to do it.

Here's my proposal, which could easily be made to work for this particular case but would require more planning and implementation effort to make it work for the larger class of all related failures: Instead of executing the :init functions in a new runloop from IMCC, we add them to the scheduler and schedule them to execute in the parent runloop after IMCC returns (in this case, directly after the invokecc opcode on the PIR compreg). In this way we integrate this better with the scheduler and prevent ever creating a child runloop, which prevents problems from multi-runloop interaction.

This type of solution could also be extended to almost every other case where a child runloop is created such as in vtable overrides for Object PMC instead of calling the override directly, we add it to the scheduler and execute some sort of continuation that takes us into the override and then returns to the point in the parent control flow where the vtable was called). Again, more details needed to be worked out for this idea to become a reality.

Once we decide how we want to resolve this problem (and there are other options besides the one I mention here), it should be straight-forward to resolve it. I would like to hear ideas from people so we can start planning a path forward.

Change History

  Changed 5 years ago by whiteknight

  • owner set to whiteknight

  Changed 4 years ago by jkeenan

See also TT #993.

  Changed 4 years ago by whiteknight

  • status changed from new to assigned

The currently-accepted workaround for the inferior runloops problem is to use the finalize opcode. This ticket can be closed after the finalize opcode is no-longer experimental (TT #1635) and once a few tests have been added to show that it resolves this issue.

  Changed 4 years ago by coke

  • type changed from RFC to bug

#1151 was closed as a duplicate of this bug.

follow-up: ↓ 6   Changed 4 years ago by whiteknight

  • status changed from assigned to closed
  • resolution set to fixed

finalize is no longer experimental. We can close this ticket.

in reply to: ↑ 5   Changed 4 years ago by coke

Replying to whiteknight:

finalize is no longer experimental. We can close this ticket.

2 upvotes, no objections at:  http://irclog.perlgeek.de/parrotsketch/2010-11-23#i_3024695

  Changed 4 years ago by whiteknight

  • status changed from closed to reopened
  • resolution fixed deleted

Coke, you're right. I was looking at the wrong ticket. Finalize is still experimental, for now. Reopened.

  Changed 4 years ago by whiteknight

  • status changed from reopened to closed
  • resolution set to fixed

as of 02de970, the finalize op is no longer experimental. Closing tickets.

Note: See TracTickets for help on using tickets.