1""" 2Tests basic UndefinedBehaviorSanitizer support (detecting an alignment error). 3""" 4 5import os 6import lldb 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test.decorators import * 9import lldbsuite.test.lldbutil as lldbutil 10import json 11 12 13class UbsanBasicTestCase(TestBase): 14 @skipUnlessUndefinedBehaviorSanitizer 15 @no_debug_info_test 16 def test(self): 17 self.build() 18 self.ubsan_tests() 19 20 def setUp(self): 21 # Call super's setUp(). 22 TestBase.setUp(self) 23 self.line_align = line_number("main.c", "// align line") 24 25 def ubsan_tests(self): 26 # Load the test 27 exe = self.getBuildArtifact("a.out") 28 target = self.dbg.CreateTarget(exe) 29 self.assertTrue(target, VALID_TARGET) 30 self.registerSanitizerLibrariesWithTarget(target) 31 32 self.runCmd("run") 33 34 process = self.dbg.GetSelectedTarget().process 35 thread = process.GetSelectedThread() 36 frame = thread.GetSelectedFrame() 37 38 # the stop reason of the thread should be breakpoint. 39 self.expect( 40 "thread list", 41 "A ubsan issue should be detected", 42 substrs=["stopped", "stop reason ="], 43 ) 44 45 stop_reason = thread.GetStopReason() 46 self.assertStopReason(stop_reason, lldb.eStopReasonInstrumentation) 47 48 # test that the UBSan dylib is present 49 self.expect( 50 "image lookup -n __ubsan_on_report", 51 "__ubsan_on_report should be present", 52 substrs=["1 match found"], 53 ) 54 55 # We should be stopped in __ubsan_on_report 56 self.assertIn("__ubsan_on_report", frame.GetFunctionName()) 57 58 # The stopped thread backtrace should contain either 'align line' 59 found = False 60 for i in range(thread.GetNumFrames()): 61 frame = thread.GetFrameAtIndex(i) 62 if frame.GetLineEntry().GetFileSpec().GetFilename() == "main.c": 63 if frame.GetLineEntry().GetLine() == self.line_align: 64 found = True 65 self.assertTrue(found) 66 67 backtraces = thread.GetStopReasonExtendedBacktraces( 68 lldb.eInstrumentationRuntimeTypeUndefinedBehaviorSanitizer 69 ) 70 self.assertEqual(backtraces.GetSize(), 1) 71 72 self.expect( 73 "thread info -s", 74 "The extended stop info should contain the UBSan provided fields", 75 substrs=[ 76 "col", 77 "description", 78 "filename", 79 "instrumentation_class", 80 "line", 81 "memory_address", 82 ], 83 ) 84 85 output_lines = self.res.GetOutput().split("\n") 86 json_line = "\n".join(output_lines[2:]) 87 data = json.loads(json_line) 88 89 self.assertEqual(data["instrumentation_class"], "UndefinedBehaviorSanitizer") 90 self.assertEqual(data["description"], "misaligned-pointer-use") 91 self.assertEqual(os.path.basename(data["filename"]), "main.c") 92 self.assertEqual(data["line"], self.line_align) 93 94 for count in range(0, 8): 95 process.Continue() 96 stop_reason = thread.GetStopReason() 97 self.assertEqual( 98 stop_reason, 99 lldb.eStopReasonInstrumentation, 100 "Round {0} wasn't instrumentation".format(count), 101 ) 102