]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: symbolize wrappers as a last resort in race tracebacks
authorAustin Clements <austin@google.com>
Mon, 22 May 2023 23:12:54 +0000 (19:12 -0400)
committerGopher Robot <gobot@golang.org>
Tue, 23 May 2023 19:14:02 +0000 (19:14 +0000)
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>

src/runtime/race.go
src/runtime/race/output_test.go

index c03866fd948e636564d94a0541ca927a8d9eea93..e2767f0324e7b2f0985d506312d82242adb4b441 100644 (file)
@@ -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
                        }
 
index 0dcdabe641107fc6647c5c2dadd15c85553e13ef..4c2c3397cf8dec87e1d1ebe837965b081a974d26 100644 (file)
@@ -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]+
+
+`}},
 }