• Russ Cox's avatar
    runtime, cmd/gc, cmd/ld: ignore method wrappers in recover · 7276c02b
    Russ Cox authored
    Bug #1:
    
    Issue 5406 identified an interesting case:
            defer iface.M()
    may end up calling a wrapper that copies an indirect receiver
    from the iface value and then calls the real M method. That's
    two calls down, not just one, and so recover() == nil always
    in the real M method, even during a panic.
    
    [For the purposes of this entire discussion, a wrapper's
    implementation is a function containing an ordinary call, not
    the optimized tail call form that is somtimes possible. The
    tail call does not create a second frame, so it is already
    handled correctly.]
    
    Fix this bug by introducing g->panicwrap, which counts the
    number of bytes on current stack segment that are due to
    wrapper calls that should not count against the recover
    check. All wrapper functions must now adjust g->panicwrap up
    on entry and back down on exit. This adds slightly to their
    expense; on the x86 it is a single instruction at entry and
    exit; on the ARM it is three. However, the alternative is to
    make a call to recover depend on being able to walk the stack,
    which I very much want to avoid. We have enough problems
    walking the stack for garbage collection and profiling.
    Also, if performance is critical in a specific case, it is already
    faster to use a pointer receiver and avoid this kind of wrapper
    entirely.
    
    Bug #2:
    
    The old code, which did not consider the possibility of two
    calls, already contained a check to see if the call had split
    its stack and so the panic-created segment was one behind the
    current segment. In the wrapper case, both of the two calls
    might split their stacks, so the panic-created segment can be
    two behind the current segment.
    
    Fix this by propagating the Stktop.panic flag forward during
    stack splits instead of looking backward during recover.
    
    Fixes #5406.
    
    R=golang-dev, iant
    CC=golang-dev
    https://golang.org/cl/13367052
    7276c02b
Name
Last commit
Last update
..
6.out.h Loading commit data...
Makefile Loading commit data...
asm.c Loading commit data...
doc.go Loading commit data...
l.h Loading commit data...
list.c Loading commit data...
mkenam Loading commit data...
obj.c Loading commit data...
optab.c Loading commit data...
pass.c Loading commit data...
prof.c Loading commit data...
span.c Loading commit data...