1""" 2Test that ASan memory history provider returns correct stack traces 3""" 4 5 6 7import lldb 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbplatform 11from lldbsuite.test import lldbutil 12 13 14class AsanTestCase(TestBase): 15 16 mydir = TestBase.compute_mydir(__file__) 17 18 @expectedFailureAll( 19 oslist=["linux"], 20 bugnumber="non-core functionality, need to reenable and fix later (DES 2014.11.07)") 21 @skipIfFreeBSD # llvm.org/pr21136 runtimes not yet available by default 22 @expectedFailureNetBSD 23 @skipUnlessAddressSanitizer 24 def test(self): 25 self.build() 26 self.asan_tests() 27 28 def setUp(self): 29 # Call super's setUp(). 30 TestBase.setUp(self) 31 self.line_malloc = line_number('main.c', '// malloc line') 32 self.line_malloc2 = line_number('main.c', '// malloc2 line') 33 self.line_free = line_number('main.c', '// free line') 34 self.line_breakpoint = line_number('main.c', '// break line') 35 36 def asan_tests(self): 37 exe = self.getBuildArtifact("a.out") 38 target = self.dbg.CreateTarget(exe) 39 self.assertTrue(target, VALID_TARGET) 40 41 self.registerSanitizerLibrariesWithTarget(target) 42 43 self.runCmd("breakpoint set -f main.c -l %d" % self.line_breakpoint) 44 45 # "memory history" command should not work without a process 46 self.expect("memory history 0", 47 error=True, 48 substrs=["invalid process"]) 49 50 self.runCmd("run") 51 52 stop_reason = self.dbg.GetSelectedTarget().process.GetSelectedThread().GetStopReason() 53 if stop_reason == lldb.eStopReasonExec: 54 # On OS X 10.10 and older, we need to re-exec to enable 55 # interceptors. 56 self.runCmd("continue") 57 58 # the stop reason of the thread should be breakpoint. 59 self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT, 60 substrs=['stopped', 'stop reason = breakpoint']) 61 62 # test that the ASan dylib is present 63 self.expect( 64 "image lookup -n __asan_describe_address", 65 "__asan_describe_address should be present", 66 substrs=['1 match found']) 67 68 # test the 'memory history' command 69 self.expect( 70 "memory history 'pointer'", 71 substrs=[ 72 'Memory deallocated by Thread', 73 'a.out`f2', 74 'main.c:%d' % self.line_free, 75 'Memory allocated by Thread', 76 'a.out`f1', 77 'main.c:%d' % self.line_malloc, 78 ]) 79 80 # do the same using SB API 81 process = self.dbg.GetSelectedTarget().process 82 val = process.GetSelectedThread().GetSelectedFrame().EvaluateExpression("pointer") 83 addr = val.GetValueAsUnsigned() 84 threads = process.GetHistoryThreads(addr) 85 self.assertEqual(threads.GetSize(), 2) 86 87 history_thread = threads.GetThreadAtIndex(0) 88 self.assertTrue(history_thread.num_frames >= 2) 89 self.assertEqual(history_thread.frames[1].GetLineEntry( 90 ).GetFileSpec().GetFilename(), "main.c") 91 self.assertEqual( 92 history_thread.frames[1].GetLineEntry().GetLine(), 93 self.line_free) 94 95 history_thread = threads.GetThreadAtIndex(1) 96 self.assertTrue(history_thread.num_frames >= 2) 97 self.assertEqual(history_thread.frames[1].GetLineEntry( 98 ).GetFileSpec().GetFilename(), "main.c") 99 self.assertEqual( 100 history_thread.frames[1].GetLineEntry().GetLine(), 101 self.line_malloc) 102 103 # let's free the container (SBThreadCollection) and see if the 104 # SBThreads still live 105 threads = None 106 self.assertTrue(history_thread.num_frames >= 2) 107 self.assertEqual(history_thread.frames[1].GetLineEntry( 108 ).GetFileSpec().GetFilename(), "main.c") 109 self.assertEqual( 110 history_thread.frames[1].GetLineEntry().GetLine(), 111 self.line_malloc) 112 113 # ASan will break when a report occurs and we'll try the API then 114 self.runCmd("continue") 115 116 self.expect( 117 "thread list", 118 "Process should be stopped due to ASan report", 119 substrs=[ 120 'stopped', 121 'stop reason = Use of deallocated memory']) 122 123 # make sure the 'memory history' command still works even when we're 124 # generating a report now 125 self.expect( 126 "memory history 'another_pointer'", 127 substrs=[ 128 'Memory allocated by Thread', 129 'a.out`f1', 130 'main.c:%d' % 131 self.line_malloc2]) 132