110 lines · python
1"""2Test the AddressSanitizer runtime support for report breakpoint and data extraction.3"""4 5import json6import lldb7from lldbsuite.test.decorators import *8from lldbsuite.test.lldbtest import *9from lldbsuite.test import lldbutil10from lldbsuite.test_event.build_exception import BuildError11 12 13class AsanTestReportDataCase(TestBase):14 @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default15 @expectedFailureNetBSD16 @skipUnlessAddressSanitizer17 @skipIf(archs=["i386"], bugnumber="llvm.org/PR36710")18 def test(self):19 self.build(make_targets=["compiler_rt-asan"])20 self.asan_tests()21 22 @skipUnlessDarwin23 @skipIf(bugnumber="rdar://109913184&143590169")24 def test_libsanitizers_asan(self):25 try:26 self.build(make_targets=["libsanitizers-asan"])27 except BuildError as e:28 self.skipTest("failed to build with libsanitizers")29 self.asan_tests(libsanitizers=True)30 31 def setUp(self):32 # Call super's setUp().33 TestBase.setUp(self)34 self.line_malloc = line_number("main.c", "// malloc line")35 self.line_malloc2 = line_number("main.c", "// malloc2 line")36 self.line_free = line_number("main.c", "// free line")37 self.line_breakpoint = line_number("main.c", "// break line")38 self.line_crash = line_number("main.c", "// BOOM line")39 self.col_crash = 1640 41 def asan_tests(self, libsanitizers=False):42 target = self.createTestTarget()43 44 if libsanitizers:45 self.runCmd("env SanitizersAddress=1 MallocSanitizerZone=1")46 else:47 self.registerSanitizerLibrariesWithTarget(target)48 49 self.runCmd("run")50 51 stop_reason = (52 self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason()53 )54 if stop_reason == lldb.eStopReasonExec:55 # On OS X 10.10 and older, we need to re-exec to enable56 # interceptors.57 self.runCmd("continue")58 59 self.expect(60 "thread list",61 "Process should be stopped due to ASan report",62 substrs=["stopped", "stop reason = Use of deallocated memory"],63 )64 65 self.assertEqual(66 self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason(),67 lldb.eStopReasonInstrumentation,68 )69 70 if self.platformIsDarwin():71 # Make sure we're not stopped in the sanitizer library but instead at the72 # point of failure in the user-code.73 self.assertEqual(self.frame().GetFunctionName(), "main")74 75 self.expect(76 "bt",77 "The backtrace should show the crashing line",78 substrs=["main.c:%d:%d" % (self.line_crash, self.col_crash)],79 )80 81 self.expect(82 "thread info -s",83 "The extended stop info should contain the ASan provided fields",84 substrs=[85 "access_size",86 "access_type",87 "address",88 "description",89 "heap-use-after-free",90 "pc",91 ],92 )93 94 output_lines = self.res.GetOutput().split("\n")95 json_line = "\n".join(output_lines[2:])96 data = json.loads(json_line)97 self.assertEqual(data["description"], "heap-use-after-free")98 self.assertEqual(data["instrumentation_class"], "AddressSanitizer")99 self.assertEqual(data["stop_type"], "fatal_error")100 101 # now let's try the SB API102 process = self.dbg.GetSelectedTarget().process103 thread = process.GetSelectedThread()104 105 s = lldb.SBStream()106 self.assertTrue(thread.GetStopReasonExtendedInfoAsJSON(s))107 s = s.GetData()108 data2 = json.loads(s)109 self.assertEqual(data, data2)110