Open
Description
The Go runtime passes cgoSymbolizer a pointer to a structure to write results. This struct is usually stack allocated. When calling in a loop from a single goroutine (e.g., via runtime.CallersFrames
), the pointer is usually the same across calls. If the goroutine migrates threads, then calls from different threads will pass the same pointer argument.
When the cgo build is using TSAN (-fsanitize=thread
, not Go's -race
), these calls from different threads will report a false race similar to:
==================
WARNING: ThreadSanitizer: data race (pid=31770)
Read of size 8 at 0x00c00005dc60 by thread T5:
#0 tcSymbolizer <null> (tsan_tracebackctxt+0x569499) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#1 runtime.asmcgocall /usr/local/google/home/mpratt/src/go/src/runtime/asm_amd64.s:921 (tsan_tracebackctxt+0x543b63) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
Previous write of size 8 at 0x00c00005dc60 by thread T3:
#0 tcSymbolizer <null> (tsan_tracebackctxt+0x5694d2) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#1 runtime.asmcgocall /usr/local/google/home/mpratt/src/go/src/runtime/asm_amd64.s:921 (tsan_tracebackctxt+0x543b63) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
Thread T5 (tid=31776, running) created by main thread at:
#0 pthread_create <null> (tsan_tracebackctxt+0x423d3b) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#1 _cgo_try_pthread_create <null> (tsan_tracebackctxt+0x569d67) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#2 _cgo_sys_thread_start <null> (tsan_tracebackctxt+0x56a08a) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#3 x_cgo_thread_start <null> (tsan_tracebackctxt+0x56ab7e) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#4 runtime.asmcgocall /usr/local/google/home/mpratt/src/go/src/runtime/asm_amd64.s:949 (tsan_tracebackctxt+0x543b9c) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
Thread T3 (tid=31774, running) created by main thread at:
#0 pthread_create <null> (tsan_tracebackctxt+0x423d3b) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#1 _cgo_try_pthread_create <null> (tsan_tracebackctxt+0x569d67) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#2 _cgo_sys_thread_start <null> (tsan_tracebackctxt+0x56a08a) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#3 x_cgo_thread_start <null> (tsan_tracebackctxt+0x56ab7e) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
#4 runtime.asmcgocall /usr/local/google/home/mpratt/src/go/src/runtime/asm_amd64.s:949 (tsan_tracebackctxt+0x543b9c) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a)
SUMMARY: ThreadSanitizer: data race (/tmp/TestTSANtsan_tracebackctxt4073566884/001/tsan_tracebackctxt+0x569499) (BuildId: cb4109606cb33da489c0ec2a2bd9e97e6d4b3b6a) in tcSymbolizer
==================
https://go.dev/cl/677955 contains a reproducer test case.
To avoid similar races, cmd/cgo wraps normal cgo calls in _cgo_tsan_acquire
/ _cgo_tsan_release
. The runtime does the same when calling cgoTraceback
.
We should do the same for cgoSymbolizer
.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Todo