runtime: don't print "unexpected SPWRITE" when printing traceback

The system stack often starts with a stack transition function
like "systemstack" or "mcall", which is marked as SPWRITE. When
unwinding a system stack for printing, we want the traceback stop
at the stack switching frame, but not print the "unexpected
SPWRITE" message.

Previously before CL 525835, we don't print the "unexpected
SPWRITE" message if unwindPrintErrors is set, i.e. printing a
stack trace. This CL restores this behavior.

Another possibility is not printing the message only on the system
stack. We don't expect a stack transition function to appear in a
user G.

Change-Id: I173e89ead2cd4fbf1f0f8cca225f28718b5baebe
Reviewed-on: https://go-review.googlesource.com/c/go/+/531815
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
This commit is contained in:
Cherry Mui 2023-09-29 14:00:04 -04:00
parent b56645a87b
commit 15a274b621
2 changed files with 9 additions and 6 deletions

View File

@ -216,6 +216,12 @@ func TestPanicSystemstack(t *testing.T) {
if nUser != 2 || nSys != 2 {
t.Fatalf("want %d user stack frames in %s and %d system stack frames in %s, got %d and %d:\n%s", 2, userFunc, 2, sysFunc, nUser, nSys, string(tb))
}
// Traceback should not contain "unexpected SPWRITE" when
// unwinding the system stacks.
if bytes.Contains(tb, []byte("unexpected SPWRITE")) {
t.Errorf("unexpected \"unexpected SPWRITE\" in traceback:\n%s", tb)
}
}
func init() {

View File

@ -356,15 +356,12 @@ func (u *unwinder) resolveInternal(innermost, isSyscall bool) {
//
// uSE uPE inn | action
// T _ _ | frame.lr = 0
// F T F | frame.lr = 0; print
// F T T | frame.lr = 0
// F T _ | frame.lr = 0
// F F F | print; panic
// F F T | ignore SPWrite
if u.flags&unwindSilentErrors == 0 && !innermost {
if u.flags&(unwindPrintErrors|unwindSilentErrors) == 0 && !innermost {
println("traceback: unexpected SPWRITE function", funcname(f))
if u.flags&unwindPrintErrors == 0 {
throw("traceback")
}
throw("traceback")
}
frame.lr = 0
} else {