• 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
Name
Last commit
Last update
..
archive Loading commit data...
bufio Loading commit data...
builtin Loading commit data...
bytes Loading commit data...
cmd Loading commit data...
compress Loading commit data...
container Loading commit data...
context Loading commit data...
crypto Loading commit data...
database/sql Loading commit data...
debug Loading commit data...
encoding Loading commit data...
errors Loading commit data...
expvar Loading commit data...
flag Loading commit data...
fmt Loading commit data...
go Loading commit data...
hash Loading commit data...
html Loading commit data...
image Loading commit data...
index/suffixarray Loading commit data...
internal Loading commit data...
io Loading commit data...
log Loading commit data...
math Loading commit data...
mime Loading commit data...
net Loading commit data...
os Loading commit data...
path Loading commit data...
plugin Loading commit data...
reflect Loading commit data...
regexp Loading commit data...
runtime Loading commit data...
sort Loading commit data...
strconv Loading commit data...
strings Loading commit data...
sync Loading commit data...
syscall Loading commit data...
testing Loading commit data...
text Loading commit data...
time Loading commit data...
unicode Loading commit data...
unsafe Loading commit data...
vendor/golang_org/x Loading commit data...
Make.dist Loading commit data...
all.bash Loading commit data...
all.bat Loading commit data...
all.rc Loading commit data...
androidtest.bash Loading commit data...
bootstrap.bash Loading commit data...
buildall.bash Loading commit data...
clean.bash Loading commit data...
clean.bat Loading commit data...
clean.rc Loading commit data...
cmp.bash Loading commit data...
iostest.bash Loading commit data...
make.bash Loading commit data...
make.bat Loading commit data...
make.rc Loading commit data...
naclmake.bash Loading commit data...
nacltest.bash Loading commit data...
race.bash Loading commit data...
race.bat Loading commit data...
run.bash Loading commit data...
run.bat Loading commit data...
run.rc Loading commit data...