• Austin Clements's avatar
    runtime: fix call* signatures and deferArgs with siz=0 · a73d68e7
    Austin Clements authored
    This commit fixes two bizarrely related bugs:
    
    1. The signatures for the call* functions were wrong, indicating that
    they had only two pointer arguments instead of three. We didn't notice
    because the call* functions are defined by a macro expansion, which go
    vet doesn't see.
    
    2. deferArgs on a defer object with a zero-sized frame returned a
    pointer just past the end of the allocated object, which is illegal in
    Go (and can cause the "sweep increased allocation count" crashes).
    
    In a fascinating twist, these two bugs canceled each other out, which
    is why I'm fixing them together. The pointer returned by deferArgs is
    used in only two ways: as an argument to memmove and as an argument to
    reflectcall. memmove is NOSPLIT, so the argument was unobservable.
    reflectcall immediately tail calls one of the call* functions, which
    are not NOSPLIT, but the deferArgs pointer just happened to be the
    third argument that was accidentally marked as a scalar. Hence, when
    the garbage collector scanned the stack, it didn't see the bad
    pointer as a pointer.
    
    I believe this was all ultimately benign. In principle, stack growth
    during the reflectcall could fail to update the args pointer, but it
    never points to the stack, so it never needs to be updated. Also in
    principle, the garbage collector could fail to mark the args object
    because of the incorrect call* signatures, but in all calls to
    reflectcall (including the ones spelled "call" in the reflect package)
    the args object is kept live by the calling stack.
    
    Change-Id: Ic932c79d5f4382be23118fdd9dba9688e9169e28
    Reviewed-on: https://go-review.googlesource.com/31654
    Run-TryBot: Austin Clements <austin@google.com>
    TryBot-Result: Gobot Gobot <gobot@golang.org>
    Reviewed-by: 's avatarKeith Randall <khr@golang.org>
    a73d68e7
stubs.go 10.6 KB