Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / test / API / functionalities / tsan / basic / TestTsanBasic.py
blobde20d6ae8e2f3e56ad1c461d13068c9ee040898e
1 """
2 Tests basic ThreadSanitizer support (detecting a data race).
3 """
5 import lldb
6 from lldbsuite.test.lldbtest import *
7 from lldbsuite.test.decorators import *
8 import lldbsuite.test.lldbutil as lldbutil
9 import json
12 class TsanBasicTestCase(TestBase):
13 @expectedFailureAll(
14 oslist=["linux"],
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
19 @skipIfRemote
20 @skipUnlessThreadSanitizer
21 @no_debug_info_test
22 def test(self):
23 self.build()
24 self.tsan_tests()
26 def setUp(self):
27 # Call super's setUp().
28 TestBase.setUp(self)
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")
33 def tsan_tests(self):
34 exe = self.getBuildArtifact("a.out")
35 self.expect("file " + exe, patterns=["Current executable set to .*a.out"])
37 self.runCmd("run")
39 stop_reason = (
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
44 # interceptors.
45 self.runCmd("continue")
47 # the stop reason of the thread should be breakpoint.
48 self.expect(
49 "thread list",
50 "A data race should be detected",
51 substrs=["stopped", "stop reason = Data race detected"],
54 self.assertEqual(
55 self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),
56 lldb.eStopReasonInstrumentation,
59 # test that the TSan dylib is present
60 self.expect(
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
73 # from main.c.
74 found = False
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:
79 found = True
80 if frame.GetLineEntry().GetLine() == self.line_thread2:
81 found = True
82 self.assertTrue(found)
84 self.expect(
85 "thread info -s",
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)
109 found = False
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:
114 found = True
115 if frame.GetLineEntry().GetLine() == self.line_thread2:
116 found = True
117 self.assertTrue(found)
119 # Second backtrace is a memory operation
120 thread = backtraces.GetThreadAtIndex(1)
121 found = False
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:
126 found = True
127 if frame.GetLineEntry().GetLine() == self.line_thread2:
128 found = True
129 self.assertTrue(found)
131 self.runCmd("continue")
133 # the stop reason of the thread should be a SIGABRT.
134 self.expect(
135 "thread list",
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)
141 self.expect(
142 "thread list",
143 "We should be stopped in pthread_kill",
144 substrs=["pthread_kill"],