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
}
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]+
+
+`}},
}