prehistoricpenguin
prehistoricpenguin

Reputation: 6326

How to add breakpoint when thread sanitizer reports data-race?

There is a similar question for address sanitizers, but for thread sanitizers, it doesn't work, I have tried to break on __sanitizer_print_stack_trace, which doesn't work either.

Upvotes: 8

Views: 3237

Answers (3)

oliver
oliver

Reputation: 6781

Based on the great answer by EmployedRussian these are the last functions that are called by TSan when reporting an error:

#0  0x0000555555b836bb in __sanitizer::internal__exit(int) ()
#1  0x0000555555b8c4b4 in __sanitizer::Die() ()
#2  0x0000555555c2536b in __tsan::OutputReport(__tsan::ThreadState*, __tsan::ScopedReport const&) ()
#3  0x0000555555c265bd in __tsan::ReportRace(__tsan::ThreadState*, __tsan::RawShadow*, __tsan::Shadow, __tsan::Shadow, unsigned long) ()

So b __tsan::ReportRace or b __tsan::OutputReport are good approaches to stop in GDB when TSan reports a data race (or any other error).

Upvotes: 1

peacetype
peacetype

Reputation: 2068

The first time I enabled Thread Sanitizer on my project, Xcode helpfully added a breakpoint for me in the Breakpoint Navigator. But I deleted it when I was done testing. Now I need it again and Xcode didn't create it for me when I enabled Thread Sanitizer again.

Note that I am using Xcode 11.0 here.

To manually re-create this breakpoint, you need to have the Breakpoint Navigator open. Then click the plus button (+) at the bottom-left of the navigator and select Runtime Issue Breakpoint from the pop-up menu. This adds the breakpoint to the navigator, and a window appears.

thread sanitizer breakpoint

From the Type drop-down list, select Thread Sanitizer.

There you go! Silly that this option is buried way down there. But I also found it helpful to note that there are more options for different kinds of breakpoints available from that plus button menu than there are from the main Xcode drop-down menu Debug > Breakpoints.

Upvotes: 7

Employed Russian
Employed Russian

Reputation: 213829

  1. Run the program under GDB, set breakpoints on exit and _exit. On Linux, also set catch syscall exit_group.
  2. set halt_on_error=1 in TSAN_OPTIONS to ask thread sanitizer to exit on first error:
(gdb) set env TSAN_OPTIONS=halt_on_error=1
(gdb) run
... error should be reported and one of the breakpoints should fire.
  1. Profit.

P.S. When the breakpoint is hit, use GDB where command to see how the error is reported. Setting a breakpoint on some kind of __tsan_report_error that is likely on the stack will probably work even without setting halt_on_error.

Upvotes: 8

Related Questions