1""" 2Test basics of mini dump debugging. 3""" 4 5import lldb 6from lldbsuite.test.decorators import * 7from lldbsuite.test.lldbtest import * 8from lldbsuite.test import lldbutil 9 10 11class MiniDumpTestCase(TestBase): 12 NO_DEBUG_INFO_TESTCASE = True 13 14 def test_process_info_in_mini_dump(self): 15 """Test that lldb can read the process information from the minidump.""" 16 # target create -c fizzbuzz_no_heap.dmp 17 self.dbg.CreateTarget("") 18 self.target = self.dbg.GetSelectedTarget() 19 self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 20 self.assertTrue(self.process, PROCESS_IS_VALID) 21 self.assertEqual(self.process.GetNumThreads(), 1) 22 self.assertEqual(self.process.GetProcessID(), 4440) 23 24 def test_thread_info_in_mini_dump(self): 25 """Test that lldb can read the thread information from the minidump.""" 26 # target create -c fizzbuzz_no_heap.dmp 27 self.dbg.CreateTarget("") 28 self.target = self.dbg.GetSelectedTarget() 29 self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 30 # This process crashed due to an access violation (0xc0000005) in its 31 # one and only thread. 32 self.assertEqual(self.process.GetNumThreads(), 1) 33 thread = self.process.GetThreadAtIndex(0) 34 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonException) 35 stop_description = thread.GetStopDescription(256) 36 self.assertIn("0xc0000005", stop_description) 37 38 def test_modules_in_mini_dump(self): 39 """Test that lldb can read the list of modules from the minidump.""" 40 # target create -c fizzbuzz_no_heap.dmp 41 self.dbg.CreateTarget("") 42 self.target = self.dbg.GetSelectedTarget() 43 self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 44 self.assertTrue(self.process, PROCESS_IS_VALID) 45 expected_modules = [ 46 { 47 "filename": r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug\fizzbuzz.exe", 48 "uuid": "0F45B791-9A96-46F9-BF8F-2D6076EA421A-00000011", 49 }, 50 { 51 "filename": r"C:\Windows\SysWOW64\ntdll.dll", 52 "uuid": "BBB0846A-402C-4052-A16B-67650BBFE6B0-00000002", 53 }, 54 { 55 "filename": r"C:\Windows\SysWOW64\kernel32.dll", 56 "uuid": "E5CB7E1B-005E-4113-AB98-98D6913B52D8-00000002", 57 }, 58 { 59 "filename": r"C:\Windows\SysWOW64\KERNELBASE.dll", 60 "uuid": "0BF95241-CB0D-4BD4-AC5D-186A6452E522-00000001", 61 }, 62 { 63 "filename": r"C:\Windows\System32\MSVCP120D.dll", 64 "uuid": "3C05516E-57E7-40EB-8D3F-9722C5BD80DD-00000001", 65 }, 66 { 67 "filename": r"C:\Windows\System32\MSVCR120D.dll", 68 "uuid": "6382FB86-46C4-4046-AE42-8D97B3F91FF2-00000001", 69 }, 70 ] 71 self.assertEqual(self.target.GetNumModules(), len(expected_modules)) 72 for module, expected in zip(self.target.modules, expected_modules): 73 self.assertTrue(module.IsValid()) 74 self.assertEqual(module.file.fullpath, expected["filename"]) 75 self.assertEqual(module.GetUUIDString(), expected["uuid"]) 76 77 def test_breakpad_uuid_matching(self): 78 """Test that the uuid computation algorithms in minidump and breakpad 79 files match.""" 80 self.target = self.dbg.CreateTarget("") 81 self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 82 self.assertTrue(self.process, PROCESS_IS_VALID) 83 self.expect( 84 "target symbols add fizzbuzz.syms", 85 substrs=[ 86 "symbol file", 87 "fizzbuzz.syms", 88 "has been added to", 89 "fizzbuzz.exe", 90 ], 91 ), 92 self.assertTrue(self.target.modules[0].FindSymbol("main")) 93 94 @skipIfLLVMTargetMissing("X86") 95 def test_stack_info_in_mini_dump(self): 96 """Test that we can see a trivial stack in a VS-generate mini dump.""" 97 # target create -c fizzbuzz_no_heap.dmp 98 self.dbg.CreateTarget("") 99 self.target = self.dbg.GetSelectedTarget() 100 self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 101 self.assertEqual(self.process.GetNumThreads(), 1) 102 thread = self.process.GetThreadAtIndex(0) 103 104 pc_list = [ 105 0x00164D14, 106 0x00167C79, 107 0x00167E6D, 108 0x7510336A, 109 0x77759882, 110 0x77759855, 111 ] 112 113 self.assertEqual(thread.GetNumFrames(), len(pc_list)) 114 for i in range(len(pc_list)): 115 frame = thread.GetFrameAtIndex(i) 116 self.assertTrue(frame.IsValid()) 117 self.assertEqual(frame.GetPC(), pc_list[i]) 118 self.assertTrue(frame.GetModule().IsValid()) 119 120 @skipUnlessWindows # Minidump saving works only on windows 121 def test_deeper_stack_in_mini_dump(self): 122 """Test that we can examine a more interesting stack in a mini dump.""" 123 self.build() 124 exe = self.getBuildArtifact("a.out") 125 core = self.getBuildArtifact("core.dmp") 126 try: 127 # Set a breakpoint and capture a mini dump. 128 target = self.dbg.CreateTarget(exe) 129 breakpoint = target.BreakpointCreateByName("bar") 130 process = target.LaunchSimple( 131 None, None, self.get_process_working_directory() 132 ) 133 self.assertState(process.GetState(), lldb.eStateStopped) 134 self.assertTrue(process.SaveCore(core)) 135 self.assertTrue(os.path.isfile(core)) 136 self.assertSuccess(process.Kill()) 137 138 # Launch with the mini dump, and inspect the stack. 139 target = self.dbg.CreateTarget(None) 140 process = target.LoadCore(core) 141 thread = process.GetThreadAtIndex(0) 142 143 expected_stack = {0: "bar", 1: "foo", 2: "main"} 144 self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack)) 145 for index, name in expected_stack.items(): 146 frame = thread.GetFrameAtIndex(index) 147 self.assertTrue(frame.IsValid()) 148 function_name = frame.GetFunctionName() 149 self.assertIn(name, function_name) 150 151 finally: 152 # Clean up the mini dump file. 153 self.assertTrue(self.dbg.DeleteTarget(target)) 154 if os.path.isfile(core): 155 os.unlink(core) 156 157 @skipUnlessWindows # Minidump saving works only on windows 158 def test_local_variables_in_mini_dump(self): 159 """Test that we can examine local variables in a mini dump.""" 160 self.build() 161 exe = self.getBuildArtifact("a.out") 162 core = self.getBuildArtifact("core.dmp") 163 try: 164 # Set a breakpoint and capture a mini dump. 165 target = self.dbg.CreateTarget(exe) 166 breakpoint = target.BreakpointCreateByName("bar") 167 process = target.LaunchSimple( 168 None, None, self.get_process_working_directory() 169 ) 170 self.assertState(process.GetState(), lldb.eStateStopped) 171 self.assertTrue(process.SaveCore(core)) 172 self.assertTrue(os.path.isfile(core)) 173 self.assertSuccess(process.Kill()) 174 175 # Launch with the mini dump, and inspect a local variable. 176 target = self.dbg.CreateTarget(None) 177 process = target.LoadCore(core) 178 thread = process.GetThreadAtIndex(0) 179 frame = thread.GetFrameAtIndex(0) 180 value = frame.EvaluateExpression("x") 181 self.assertEqual(value.GetValueAsSigned(), 3) 182 183 finally: 184 # Clean up the mini dump file. 185 self.assertTrue(self.dbg.DeleteTarget(target)) 186 if os.path.isfile(core): 187 os.unlink(core) 188