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