]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: ignore SPWRITE in syscall functions
authorRuss Cox <rsc@golang.org>
Fri, 19 Feb 2021 11:01:25 +0000 (06:01 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 19 Feb 2021 16:09:17 +0000 (16:09 +0000)
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>

src/runtime/traceback.go

index eb185eecd36c238b666e26c0cfec27ec9a2a1d5d..53eb689848268aee2b4c0787cec8cc00a9c563c1 100644 (file)
@@ -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.