aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/traceback.go
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2021-02-19 06:01:25 -0500
committerRuss Cox <rsc@golang.org>2021-02-19 16:09:17 +0000
commit02e5a8fdfcc8e237f5b55618ccbe9ad845014427 (patch)
tree111de57074d94e075524e2c824a091c849940a3e /src/runtime/traceback.go
parentfa18f224c378f5831210077944e5df718efb8df5 (diff)
downloadgo-02e5a8fdfcc8e237f5b55618ccbe9ad845014427.tar.gz
go-02e5a8fdfcc8e237f5b55618ccbe9ad845014427.zip
runtime: ignore SPWRITE in syscall functions
netbsd/amd64's Syscall9 changes SP using ADD and SUB, which are treated as SPWRITEs (they are not accounted for in the sp-adjust tracking, and there are too many functions that would report mismatched stack adjustments at RET if they were). A traceback starting in Syscall9 as saved by entersyscall complains about the SPWRITE-ness unnecessarily, since the PC/SP are saved at the start of the function. Ignore SPWRITE in that case. netbsd/arm's Syscall6 also changes SP (R13), using a direct write. So even if we could handle the ADD/SUB in the amd64 case or rewrote that assembly, we'd still be stuck with a more difficult problem in this case. Ignoring the SPWRITE fixes it. Example crashes: https://build.golang.org/log/160fc7b051a2cf90782b75a99984fff129329e66 https://build.golang.org/log/7879e2fecdb400eee616294285e1f952e5b17301 Change-Id: I0c8e9696066e90dafed6d4a93d11697da23f0080 Reviewed-on: https://go-review.googlesource.com/c/go/+/294072 Reviewed-by: Cherry Zhang <cherryyz@google.com> Trust: Russ Cox <rsc@golang.org> Run-TryBot: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/runtime/traceback.go')
-rw-r--r--src/runtime/traceback.go6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/runtime/traceback.go b/src/runtime/traceback.go
index eb185eecd36..53eb6898482 100644
--- a/src/runtime/traceback.go
+++ b/src/runtime/traceback.go
@@ -174,6 +174,12 @@ func gentraceback(pc0, sp0, lr0 uintptr, gp *g, skip int, pcbuf *uintptr, max in
// So we don't need to exclude it with the other SP-writing functions.
flag &^= funcFlag_SPWRITE
}
+ if frame.pc == pc0 && frame.sp == sp0 && pc0 == gp.syscallpc && sp0 == gp.syscallsp {
+ // Some Syscall functions write to SP, but they do so only after
+ // saving the entry PC/SP using entersyscall.
+ // Since we are using the entry PC/SP, the later SP write doesn't matter.
+ flag &^= funcFlag_SPWRITE
+ }
// Found an actual function.
// Derive frame pointer and link register.