summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
diff options
context:
space:
mode:
authorKuba Brecka <kuba.brecka@gmail.com>2016-03-23 15:36:22 +0000
committerKuba Brecka <kuba.brecka@gmail.com>2016-03-23 15:36:22 +0000
commit6a83143650aeb02e9c53bd5f7b7b5253a6c8b157 (patch)
tree84b85e5d71064a4c24d0100811f7114f2143ab2f /lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
parentd68ed85401a5b1d40fb6065bcbd363e1bd78402d (diff)
downloadbcm5719-llvm-6a83143650aeb02e9c53bd5f7b7b5253a6c8b157.tar.gz
bcm5719-llvm-6a83143650aeb02e9c53bd5f7b7b5253a6c8b157.zip
Add ThreadSanitizer debugging support.
This patch adds ThreadSanitizer support into LLDB: - Adding a new InstrumentationRuntime plugin, ThreadSanitizerRuntime, in the same way ASan is implemented. - A breakpoint stops in `__tsan_on_report`, then we extract all sorts of information by evaluating an expression. We then populate this into StopReasonExtendedInfo. - SBThread gets a new API, SBThread::GetStopReasonExtendedBacktraces(), which returns TSan’s backtraces in the form of regular SBThreads. Non-TSan stop reasons return an empty collection. - Added some test cases. Reviewed by Greg Clayton. llvm-svn: 264162
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py')
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py112
1 files changed, 112 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py b/lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
new file mode 100644
index 00000000000..eb0c5df30c8
--- /dev/null
+++ b/lldb/packages/Python/lldbsuite/test/functionalities/tsan/basic/TestTsanBasic.py
@@ -0,0 +1,112 @@
+"""
+Tests basic ThreadSanitizer support (detecting a data race).
+"""
+
+import os, time
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+import json
+
+class TsanBasicTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @expectedFailureAll(oslist=["linux"], bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)")
+ @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default
+ @skipIfRemote
+ @skipUnlessCompilerRt
+ def test (self):
+ self.build ()
+ self.tsan_tests ()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ self.line_malloc = line_number('main.c', '// malloc line')
+ self.line_thread1 = line_number('main.c', '// thread1 line')
+ self.line_thread2 = line_number('main.c', '// thread2 line')
+
+ def tsan_tests (self):
+ exe = os.path.join (os.getcwd(), "a.out")
+ self.expect("file " + exe, patterns = [ "Current executable set to .*a.out" ])
+
+ self.runCmd("run")
+
+ # the stop reason of the thread should be breakpoint.
+ self.expect("thread list", "A data race should be detected",
+ substrs = ['stopped', 'stop reason = Data race detected'])
+
+ self.assertEqual(self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), lldb.eStopReasonInstrumentation)
+
+ # test that the TSan dylib is present
+ self.expect("image lookup -n __tsan_get_current_report", "__tsan_get_current_report should be present",
+ substrs = ['1 match found'])
+
+ # We should be stopped in __tsan_on_report
+ process = self.dbg.GetSelectedTarget().process
+ thread = process.GetSelectedThread()
+ frame = thread.GetSelectedFrame()
+ self.assertTrue("__tsan_on_report" in frame.GetFunctionName())
+
+ # The stopped thread backtrace should contain either line1 or line2 from main.c.
+ found = False
+ for i in range(0, thread.GetNumFrames()):
+ frame = thread.GetFrameAtIndex(i)
+ if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
+ if frame.GetLineEntry().GetLine() == self.line_thread1:
+ found = True
+ if frame.GetLineEntry().GetLine() == self.line_thread2:
+ found = True
+ self.assertTrue(found)
+
+ self.expect("thread info -s", "The extended stop info should contain the TSan provided fields",
+ substrs = ["instrumentation_class", "description", "mops"])
+
+ output_lines = self.res.GetOutput().split('\n')
+ json_line = '\n'.join(output_lines[2:])
+ data = json.loads(json_line)
+ self.assertEqual(data["instrumentation_class"], "ThreadSanitizer")
+ self.assertEqual(data["description"], "data-race")
+ self.assertEqual(len(data["mops"]), 2)
+
+ backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeAddressSanitizer)
+ self.assertEqual(backtraces.GetSize(), 0)
+
+ backtraces = thread.GetStopReasonExtendedBacktraces(lldb.eInstrumentationRuntimeTypeThreadSanitizer)
+ self.assertTrue(backtraces.GetSize() >= 2)
+
+ # First backtrace is a memory operation
+ thread = backtraces.GetThreadAtIndex(0)
+ found = False
+ for i in range(0, thread.GetNumFrames()):
+ frame = thread.GetFrameAtIndex(i)
+ if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
+ if frame.GetLineEntry().GetLine() == self.line_thread1:
+ found = True
+ if frame.GetLineEntry().GetLine() == self.line_thread2:
+ found = True
+ self.assertTrue(found)
+
+ # Second backtrace is a memory operation
+ thread = backtraces.GetThreadAtIndex(1)
+ found = False
+ for i in range(0, thread.GetNumFrames()):
+ frame = thread.GetFrameAtIndex(i)
+ if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c":
+ if frame.GetLineEntry().GetLine() == self.line_thread1:
+ found = True
+ if frame.GetLineEntry().GetLine() == self.line_thread2:
+ found = True
+ self.assertTrue(found)
+
+ self.runCmd("continue")
+
+ # the stop reason of the thread should be a SIGABRT.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped', 'stop reason = signal SIGABRT'])
+
+ # test that we're in pthread_kill now (TSan abort the process)
+ self.expect("thread list", "We should be stopped in pthread_kill",
+ substrs = ['pthread_kill'])
OpenPOWER on IntegriCloud