2 Tests basic ThreadSanitizer support (detecting a data race).
6 from lldbsuite
.test
.lldbtest
import *
7 from lldbsuite
.test
.decorators
import *
8 import lldbsuite
.test
.lldbutil
as lldbutil
12 class TsanBasicTestCase(TestBase
):
15 bugnumber
="non-core functionality, need to reenable and fix later (DES 2014.11.07)",
17 @expectedFailureNetBSD
18 @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
20 @skipUnlessThreadSanitizer
27 # Call super's setUp().
29 self
.line_malloc
= line_number("main.c", "// malloc line")
30 self
.line_thread1
= line_number("main.c", "// thread1 line")
31 self
.line_thread2
= line_number("main.c", "// thread2 line")
34 exe
= self
.getBuildArtifact("a.out")
35 self
.expect("file " + exe
, patterns
=["Current executable set to .*a.out"])
40 self
.dbg
.GetSelectedTarget().process
.GetSelectedThread().GetStopReason()
42 if stop_reason
== lldb
.eStopReasonExec
:
43 # On OS X 10.10 and older, we need to re-exec to enable
45 self
.runCmd("continue")
47 # the stop reason of the thread should be breakpoint.
50 "A data race should be detected",
51 substrs
=["stopped", "stop reason = Data race detected"],
55 self
.dbg
.GetSelectedTarget().process
.GetSelectedThread().GetStopReason(),
56 lldb
.eStopReasonInstrumentation
,
59 # test that the TSan dylib is present
61 "image lookup -n __tsan_get_current_report",
62 "__tsan_get_current_report should be present",
63 substrs
=["1 match found"],
66 # We should be stopped in __tsan_on_report
67 process
= self
.dbg
.GetSelectedTarget().process
68 thread
= process
.GetSelectedThread()
69 frame
= thread
.GetSelectedFrame()
70 self
.assertIn("__tsan_on_report", frame
.GetFunctionName())
72 # The stopped thread backtrace should contain either line1 or line2
75 for i
in range(0, thread
.GetNumFrames()):
76 frame
= thread
.GetFrameAtIndex(i
)
77 if frame
.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
78 if frame
.GetLineEntry().GetLine() == self
.line_thread1
:
80 if frame
.GetLineEntry().GetLine() == self
.line_thread2
:
82 self
.assertTrue(found
)
86 "The extended stop info should contain the TSan provided fields",
87 substrs
=["instrumentation_class", "description", "mops"],
90 output_lines
= self
.res
.GetOutput().split("\n")
91 json_line
= "\n".join(output_lines
[2:])
92 data
= json
.loads(json_line
)
93 self
.assertEqual(data
["instrumentation_class"], "ThreadSanitizer")
94 self
.assertEqual(data
["issue_type"], "data-race")
95 self
.assertEqual(len(data
["mops"]), 2)
97 backtraces
= thread
.GetStopReasonExtendedBacktraces(
98 lldb
.eInstrumentationRuntimeTypeAddressSanitizer
100 self
.assertEqual(backtraces
.GetSize(), 0)
102 backtraces
= thread
.GetStopReasonExtendedBacktraces(
103 lldb
.eInstrumentationRuntimeTypeThreadSanitizer
105 self
.assertTrue(backtraces
.GetSize() >= 2)
107 # First backtrace is a memory operation
108 thread
= backtraces
.GetThreadAtIndex(0)
110 for i
in range(0, thread
.GetNumFrames()):
111 frame
= thread
.GetFrameAtIndex(i
)
112 if frame
.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
113 if frame
.GetLineEntry().GetLine() == self
.line_thread1
:
115 if frame
.GetLineEntry().GetLine() == self
.line_thread2
:
117 self
.assertTrue(found
)
119 # Second backtrace is a memory operation
120 thread
= backtraces
.GetThreadAtIndex(1)
122 for i
in range(0, thread
.GetNumFrames()):
123 frame
= thread
.GetFrameAtIndex(i
)
124 if frame
.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
125 if frame
.GetLineEntry().GetLine() == self
.line_thread1
:
127 if frame
.GetLineEntry().GetLine() == self
.line_thread2
:
129 self
.assertTrue(found
)
131 self
.runCmd("continue")
133 # the stop reason of the thread should be a SIGABRT.
136 "We should be stopped due a SIGABRT",
137 substrs
=["stopped", "stop reason = signal SIGABRT"],
140 # test that we're in pthread_kill now (TSan abort the process)
143 "We should be stopped in pthread_kill",
144 substrs
=["pthread_kill"],