199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest the AddressSanitizer runtime support for report breakpoint and data extraction. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprecht 699451b44SJordan Rupprechtimport json 799451b44SJordan Rupprechtimport lldb 899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 11*988ffd06SUsama Hameedfrom lldbsuite.test_event.build_exception import BuildError 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprechtclass AsanTestReportDataCase(TestBase): 1499451b44SJordan Rupprecht @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default 1599451b44SJordan Rupprecht @expectedFailureNetBSD 1699451b44SJordan Rupprecht @skipUnlessAddressSanitizer 172238dcc3SJonas Devlieghere @skipIf(archs=["i386"], bugnumber="llvm.org/PR36710") 1899451b44SJordan Rupprecht def test(self): 19*988ffd06SUsama Hameed self.build(make_targets=["asan"]) 2099451b44SJordan Rupprecht self.asan_tests() 2199451b44SJordan Rupprecht 22*988ffd06SUsama Hameed @skipIf(oslist=no_match(["macosx"])) 23*988ffd06SUsama Hameed def test_libsanitizers_asan(self): 24*988ffd06SUsama Hameed try: 25*988ffd06SUsama Hameed self.build(make_targets=["libsanitizers"]) 26*988ffd06SUsama Hameed except BuildError as e: 27*988ffd06SUsama Hameed self.skipTest("failed to build with libsanitizers") 28*988ffd06SUsama Hameed self.asan_tests(libsanitizers=True) 29*988ffd06SUsama Hameed 3099451b44SJordan Rupprecht def setUp(self): 3199451b44SJordan Rupprecht # Call super's setUp(). 3299451b44SJordan Rupprecht TestBase.setUp(self) 332238dcc3SJonas Devlieghere self.line_malloc = line_number("main.c", "// malloc line") 342238dcc3SJonas Devlieghere self.line_malloc2 = line_number("main.c", "// malloc2 line") 352238dcc3SJonas Devlieghere self.line_free = line_number("main.c", "// free line") 362238dcc3SJonas Devlieghere self.line_breakpoint = line_number("main.c", "// break line") 372238dcc3SJonas Devlieghere self.line_crash = line_number("main.c", "// BOOM line") 3899451b44SJordan Rupprecht self.col_crash = 16 3999451b44SJordan Rupprecht 40*988ffd06SUsama Hameed def asan_tests(self, libsanitizers=False): 4154c26872SRaphael Isemann target = self.createTestTarget() 4299451b44SJordan Rupprecht 43*988ffd06SUsama Hameed if libsanitizers: 44*988ffd06SUsama Hameed self.runCmd( 45*988ffd06SUsama Hameed "env SanitizersAddress=1 MallocSanitizerZone=1 MallocSecureAllocator=0" 46*988ffd06SUsama Hameed ) 47*988ffd06SUsama Hameed else: 4899451b44SJordan Rupprecht self.registerSanitizerLibrariesWithTarget(target) 4999451b44SJordan Rupprecht 5099451b44SJordan Rupprecht self.runCmd("run") 5199451b44SJordan Rupprecht 522238dcc3SJonas Devlieghere stop_reason = ( 532238dcc3SJonas Devlieghere self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() 542238dcc3SJonas Devlieghere ) 5599451b44SJordan Rupprecht if stop_reason == lldb.eStopReasonExec: 5699451b44SJordan Rupprecht # On OS X 10.10 and older, we need to re-exec to enable 5799451b44SJordan Rupprecht # interceptors. 5899451b44SJordan Rupprecht self.runCmd("continue") 5999451b44SJordan Rupprecht 6099451b44SJordan Rupprecht self.expect( 6199451b44SJordan Rupprecht "thread list", 6299451b44SJordan Rupprecht "Process should be stopped due to ASan report", 632238dcc3SJonas Devlieghere substrs=["stopped", "stop reason = Use of deallocated memory"], 642238dcc3SJonas Devlieghere ) 6599451b44SJordan Rupprecht 6699451b44SJordan Rupprecht self.assertEqual( 6799451b44SJordan Rupprecht self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(), 682238dcc3SJonas Devlieghere lldb.eStopReasonInstrumentation, 692238dcc3SJonas Devlieghere ) 7099451b44SJordan Rupprecht 712238dcc3SJonas Devlieghere self.expect( 722238dcc3SJonas Devlieghere "bt", 732238dcc3SJonas Devlieghere "The backtrace should show the crashing line", 742238dcc3SJonas Devlieghere substrs=["main.c:%d:%d" % (self.line_crash, self.col_crash)], 752238dcc3SJonas Devlieghere ) 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht self.expect( 7899451b44SJordan Rupprecht "thread info -s", 7999451b44SJordan Rupprecht "The extended stop info should contain the ASan provided fields", 8099451b44SJordan Rupprecht substrs=[ 8199451b44SJordan Rupprecht "access_size", 8299451b44SJordan Rupprecht "access_type", 8399451b44SJordan Rupprecht "address", 8499451b44SJordan Rupprecht "description", 8599451b44SJordan Rupprecht "heap-use-after-free", 8699451b44SJordan Rupprecht "pc", 872238dcc3SJonas Devlieghere ], 882238dcc3SJonas Devlieghere ) 8999451b44SJordan Rupprecht 902238dcc3SJonas Devlieghere output_lines = self.res.GetOutput().split("\n") 912238dcc3SJonas Devlieghere json_line = "\n".join(output_lines[2:]) 9299451b44SJordan Rupprecht data = json.loads(json_line) 9399451b44SJordan Rupprecht self.assertEqual(data["description"], "heap-use-after-free") 9499451b44SJordan Rupprecht self.assertEqual(data["instrumentation_class"], "AddressSanitizer") 9599451b44SJordan Rupprecht self.assertEqual(data["stop_type"], "fatal_error") 9699451b44SJordan Rupprecht 9799451b44SJordan Rupprecht # now let's try the SB API 9899451b44SJordan Rupprecht process = self.dbg.GetSelectedTarget().process 9999451b44SJordan Rupprecht thread = process.GetSelectedThread() 10099451b44SJordan Rupprecht 10199451b44SJordan Rupprecht s = lldb.SBStream() 10299451b44SJordan Rupprecht self.assertTrue(thread.GetStopReasonExtendedInfoAsJSON(s)) 10399451b44SJordan Rupprecht s = s.GetData() 10499451b44SJordan Rupprecht data2 = json.loads(s) 10599451b44SJordan Rupprecht self.assertEqual(data, data2) 106