aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2023-05-22 19:12:54 -0400
committerGopher Robot <gobot@golang.org>2023-05-23 19:14:02 +0000
commitcb6b45a993a50b4cf24defd92a1afcc49cbf5f25 (patch)
tree1f1660b72ad90f2bd2f7b5c651c4961a2393b758
parentef2bb813c82d5a96bb0993be83a34bfccb5f8c77 (diff)
downloadgo-cb6b45a993a50b4cf24defd92a1afcc49cbf5f25.tar.gz
go-cb6b45a993a50b4cf24defd92a1afcc49cbf5f25.zip
runtime: symbolize wrappers as a last resort in race tracebacks
CL 466099 rewrote stack symbolization in race reports. Prior to this CL, physical frames consisting entirely of wrapper logical frame would print the wrapper, even though in other cases we try to avoid printing wrappers. CL 466099 unintentionally changed this behavior and now physical frames consisting entirely of wrapper frames instead fail to symbolize and print "??()". Fix this by taking the outermost wrapper frame if the entire logical frame expansion consists of wrappers. Fixes #60245. Change-Id: I13de8857e508b757ea10d1fc7a47258d7fddbfdb Reviewed-on: https://go-review.googlesource.com/c/go/+/497235 Reviewed-by: Michael Knyszek <mknyszek@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Austin Clements <austin@google.com> Auto-Submit: Austin Clements <austin@google.com>
-rw-r--r--src/runtime/race.go7
-rw-r--r--src/runtime/race/output_test.go38
2 files changed, 43 insertions, 2 deletions
diff --git a/src/runtime/race.go b/src/runtime/race.go
index c03866fd94..e2767f0324 100644
--- a/src/runtime/race.go
+++ b/src/runtime/race.go
@@ -175,8 +175,11 @@ func raceSymbolizeCode(ctx *symbolizeCodeContext) {
u, uf := newInlineUnwinder(fi, pc, nil)
for ; uf.valid(); uf = u.next(uf) {
sf := u.srcFunc(uf)
- if sf.funcID == abi.FuncIDWrapper {
- // ignore wrappers
+ if sf.funcID == abi.FuncIDWrapper && u.isInlined(uf) {
+ // Ignore wrappers, unless we're at the outermost frame of u.
+ // A non-inlined wrapper frame always means we have a physical
+ // frame consisting entirely of wrappers, in which case we'll
+ // take a outermost wrapper over nothing.
continue
}
diff --git a/src/runtime/race/output_test.go b/src/runtime/race/output_test.go
index 0dcdabe641..4c2c3397cf 100644
--- a/src/runtime/race/output_test.go
+++ b/src/runtime/race/output_test.go
@@ -439,4 +439,42 @@ Goroutine [0-9] \(running\) created at:
main\.main\(\)
.*/main.go:[0-9]+ \+0x[0-9,a-f]+
==================`}},
+ // Test symbolizing wrappers. Both (*T).f and main.func1 are wrappers.
+ // go.dev/issue/60245
+ {"wrappersym", "run", "", "atexit_sleep_ms=0", `
+package main
+import "sync"
+var wg sync.WaitGroup
+var x int
+func main() {
+ f := (*T).f
+ wg.Add(2)
+ go f(new(T))
+ f(new(T))
+ wg.Wait()
+}
+type T struct{}
+func (t T) f() {
+ x = 42
+ wg.Done()
+}
+`, []string{`==================
+WARNING: DATA RACE
+Write at 0x[0-9,a-f]+ by goroutine [0-9]:
+ main\.T\.f\(\)
+ .*/main.go:15 \+0x[0-9,a-f]+
+ main\.\(\*T\)\.f\(\)
+ <autogenerated>:1 \+0x[0-9,a-f]+
+ main\.main\.func1\(\)
+ .*/main.go:9 \+0x[0-9,a-f]+
+
+Previous write at 0x[0-9,a-f]+ by main goroutine:
+ main\.T\.f\(\)
+ .*/main.go:15 \+0x[0-9,a-f]+
+ main\.\(\*T\)\.f\(\)
+ <autogenerated>:1 \+0x[0-9,a-f]+
+ main\.main\(\)
+ .*/main.go:10 \+0x[0-9,a-f]+
+
+`}},
}