Closed
Description
The fast variant swissmap functions report the wrong PC to TSAN in their custom instrumentation, which results in incorrect stack traces when races are found and GOTRACEBACK=system
or higher (by default the runtime frame is hidden).
package main
func main() {
m := make(map[int]int)
go func() {
for {
_ = m[1]
}
}()
go func() {
for {
m[1] = 1
}
}()
select {}
}
$ GOTRACEBACK=system go run -race main.go
==================
WARNING: DATA RACE
Read at 0x00c000034030 by goroutine 6:
runtime.mapaccess1()
/usr/lib/google-golang/src/internal/runtime/maps/runtime_swiss.go:43 +0x0
main.main.func1()
/tmp/racemap/main.go:7 +0x3a
Previous write at 0x00c000034030 by goroutine 7:
runtime.mapassign()
/usr/lib/google-golang/src/internal/runtime/maps/runtime_swiss.go:191 +0x0
main.main.func2()
/tmp/racemap/main.go:12 +0x3a
Goroutine 6 (running) created at:
main.main()
/tmp/racemap/main.go:5 +0x7c
Goroutine 7 (running) created at:
main.main()
/tmp/racemap/main.go:10 +0xc6
==================
fatal error: concurrent map read and map write
goroutine 5 gp=0xc000003dc0 m=5 mp=0xc000088008 [running]:
runtime.fatal({0x4bbb40, 0x21})
/usr/lib/google-golang/src/runtime/panic.go:1134 +0x5c fp=0xc000049760 sp=0xc000049730 pc=0x46949c
internal/runtime/maps.fatal({0x4bbb40?, 0x4a1939?})
/usr/lib/google-golang/src/runtime/panic.go:1067 +0x18 fp=0xc000049780 sp=0xc000049760 pc=0x49ad38
runtime.mapaccess1_fast64(0x4ad660, 0xc000034030, 0x1)
/usr/lib/google-golang/src/internal/runtime/maps/runtime_fast64_swiss.go:29 +0xfe fp=0xc0000497b0 sp=0xc000049780 pc=0x43b61e
main.main.func1()
/tmp/racemap/main.go:7 +0x3b fp=0xc0000497e0 sp=0xc0000497b0 pc=0x4a3b7b
runtime.goexit({})
/usr/lib/google-golang/src/runtime/asm_amd64.s:1700 +0x1 fp=0xc0000497e8 sp=0xc0000497e0 pc=0x4a02a1
created by main.main in goroutine 1
/tmp/racemap/main.go:5 +0x7d
...
In the DATA RACE report, the read should say runtime.mapaccess1_fast64
, not runtime.mapaccess1
and the write should say runtime.mapassign_fast64
, not runtime.mapassign
.
Note that the always-enabled concurrent map read/write throw got the stack correct because it is just a normal throw, but that isn't guaranteed to catch a race when TSAN does.
Thanks @mateusz834 for finding this.