1""" 2Test ThreadSanitizer when multiple different issues are found. 3""" 4 5import lldb 6from lldbsuite.test.lldbtest import * 7from lldbsuite.test.decorators import * 8import lldbsuite.test.lldbutil as lldbutil 9import json 10 11 12class TsanMultipleTestCase(TestBase): 13 @expectedFailureAll( 14 oslist=["linux"], 15 bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)", 16 ) 17 @expectedFailureNetBSD 18 @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default 19 @skipIfRemote 20 @skipUnlessThreadSanitizer 21 @add_test_categories(["objc"]) 22 def test(self): 23 self.build() 24 self.tsan_tests() 25 26 def tsan_tests(self): 27 exe = self.getBuildArtifact("a.out") 28 self.expect("file " + exe, patterns=["Current executable set to .*a.out"]) 29 30 self.runCmd("env TSAN_OPTIONS=abort_on_error=0") 31 32 self.runCmd("run") 33 34 stop_reason = ( 35 self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() 36 ) 37 if stop_reason == lldb.eStopReasonExec: 38 # On OS X 10.10 and older, we need to re-exec to enable 39 # interceptors. 40 self.runCmd("continue") 41 42 report_count = 0 43 while ( 44 self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() 45 == lldb.eStopReasonInstrumentation 46 ): 47 report_count += 1 48 49 stop_description = ( 50 self.dbg.GetSelectedTarget() 51 .process.GetSelectedThread() 52 .GetStopDescription(100) 53 ) 54 55 self.assertTrue( 56 (stop_description == "Data race detected") 57 or (stop_description == "Use of deallocated memory detected") 58 or (stop_description == "Thread leak detected") 59 or ( 60 stop_description 61 == "Use of an uninitialized or destroyed mutex detected" 62 ) 63 or ( 64 stop_description 65 == "Unlock of an unlocked mutex (or by a wrong thread) detected" 66 ) 67 ) 68 69 self.expect( 70 "thread info -s", 71 "The extended stop info should contain the TSan provided fields", 72 substrs=["instrumentation_class", "description", "mops"], 73 ) 74 75 output_lines = self.res.GetOutput().split("\n") 76 json_line = "\n".join(output_lines[2:]) 77 data = json.loads(json_line) 78 self.assertEqual(data["instrumentation_class"], "ThreadSanitizer") 79 80 backtraces = ( 81 self.dbg.GetSelectedTarget() 82 .process.GetSelectedThread() 83 .GetStopReasonExtendedBacktraces( 84 lldb.eInstrumentationRuntimeTypeThreadSanitizer 85 ) 86 ) 87 self.assertGreaterEqual(backtraces.GetSize(), 1) 88 89 self.runCmd("continue") 90 91 self.assertEqual( 92 self.dbg.GetSelectedTarget().process.GetState(), 93 lldb.eStateExited, 94 PROCESS_EXITED, 95 ) 96