199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest basics of mini dump debugging. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtfrom six import iteritems 699451b44SJordan Rupprecht 799451b44SJordan Rupprecht 899451b44SJordan Rupprechtimport lldb 999451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 1099451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 1199451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 1299451b44SJordan Rupprecht 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprechtclass MiniDumpTestCase(TestBase): 1599451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1699451b44SJordan Rupprecht 1799451b44SJordan Rupprecht def test_process_info_in_mini_dump(self): 1899451b44SJordan Rupprecht """Test that lldb can read the process information from the minidump.""" 1999451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 2099451b44SJordan Rupprecht self.dbg.CreateTarget("") 2199451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 2299451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 2399451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 2499451b44SJordan Rupprecht self.assertEqual(self.process.GetNumThreads(), 1) 2599451b44SJordan Rupprecht self.assertEqual(self.process.GetProcessID(), 4440) 2699451b44SJordan Rupprecht 2799451b44SJordan Rupprecht def test_thread_info_in_mini_dump(self): 2899451b44SJordan Rupprecht """Test that lldb can read the thread information from the minidump.""" 2999451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 3099451b44SJordan Rupprecht self.dbg.CreateTarget("") 3199451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 3299451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 3399451b44SJordan Rupprecht # This process crashed due to an access violation (0xc0000005) in its 3499451b44SJordan Rupprecht # one and only thread. 3599451b44SJordan Rupprecht self.assertEqual(self.process.GetNumThreads(), 1) 3699451b44SJordan Rupprecht thread = self.process.GetThreadAtIndex(0) 3799451b44SJordan Rupprecht self.assertEqual(thread.GetStopReason(), lldb.eStopReasonException) 3899451b44SJordan Rupprecht stop_description = thread.GetStopDescription(256) 393cc37622SDave Lee self.assertIn("0xc0000005", stop_description) 4099451b44SJordan Rupprecht 4199451b44SJordan Rupprecht def test_modules_in_mini_dump(self): 4299451b44SJordan Rupprecht """Test that lldb can read the list of modules from the minidump.""" 4399451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 4499451b44SJordan Rupprecht self.dbg.CreateTarget("") 4599451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 4699451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 4799451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 4899451b44SJordan Rupprecht expected_modules = [ 4999451b44SJordan Rupprecht { 5099451b44SJordan Rupprecht 'filename' : r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug/fizzbuzz.exe", 5199451b44SJordan Rupprecht 'uuid' : '0F45B791-9A96-46F9-BF8F-2D6076EA421A-00000011', 5299451b44SJordan Rupprecht }, 5399451b44SJordan Rupprecht { 5499451b44SJordan Rupprecht 'filename' : r"C:\Windows\SysWOW64/ntdll.dll", 5599451b44SJordan Rupprecht 'uuid' : 'BBB0846A-402C-4052-A16B-67650BBFE6B0-00000002', 5699451b44SJordan Rupprecht }, 5799451b44SJordan Rupprecht { 5899451b44SJordan Rupprecht 'filename' : r"C:\Windows\SysWOW64/kernel32.dll", 5999451b44SJordan Rupprecht 'uuid' : 'E5CB7E1B-005E-4113-AB98-98D6913B52D8-00000002', 6099451b44SJordan Rupprecht }, 6199451b44SJordan Rupprecht { 6299451b44SJordan Rupprecht 'filename' : r"C:\Windows\SysWOW64/KERNELBASE.dll", 6399451b44SJordan Rupprecht 'uuid' : '0BF95241-CB0D-4BD4-AC5D-186A6452E522-00000001', 6499451b44SJordan Rupprecht }, 6599451b44SJordan Rupprecht { 6699451b44SJordan Rupprecht 'filename' : r"C:\Windows\System32/MSVCP120D.dll", 6799451b44SJordan Rupprecht 'uuid' : '3C05516E-57E7-40EB-8D3F-9722C5BD80DD-00000001', 6899451b44SJordan Rupprecht }, 6999451b44SJordan Rupprecht { 7099451b44SJordan Rupprecht 'filename' : r"C:\Windows\System32/MSVCR120D.dll", 7199451b44SJordan Rupprecht 'uuid' : '6382FB86-46C4-4046-AE42-8D97B3F91FF2-00000001', 7299451b44SJordan Rupprecht }, 7399451b44SJordan Rupprecht ] 7499451b44SJordan Rupprecht self.assertEqual(self.target.GetNumModules(), len(expected_modules)) 7599451b44SJordan Rupprecht for module, expected in zip(self.target.modules, expected_modules): 7699451b44SJordan Rupprecht self.assertTrue(module.IsValid()) 7799451b44SJordan Rupprecht self.assertEqual(module.file.fullpath, expected['filename']) 7899451b44SJordan Rupprecht self.assertEqual(module.GetUUIDString(), expected['uuid']) 7999451b44SJordan Rupprecht 8099451b44SJordan Rupprecht def test_breakpad_uuid_matching(self): 8199451b44SJordan Rupprecht """Test that the uuid computation algorithms in minidump and breakpad 8299451b44SJordan Rupprecht files match.""" 8399451b44SJordan Rupprecht self.target = self.dbg.CreateTarget("") 8499451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 8599451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 8699451b44SJordan Rupprecht self.expect("target symbols add fizzbuzz.syms", substrs=["symbol file", 8799451b44SJordan Rupprecht "fizzbuzz.syms", "has been added to", "fizzbuzz.exe"]), 8899451b44SJordan Rupprecht self.assertTrue(self.target.modules[0].FindSymbol("main")) 8999451b44SJordan Rupprecht 9099451b44SJordan Rupprecht @skipIfLLVMTargetMissing("X86") 9199451b44SJordan Rupprecht def test_stack_info_in_mini_dump(self): 9299451b44SJordan Rupprecht """Test that we can see a trivial stack in a VS-generate mini dump.""" 9399451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 9499451b44SJordan Rupprecht self.dbg.CreateTarget("") 9599451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 9699451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 9799451b44SJordan Rupprecht self.assertEqual(self.process.GetNumThreads(), 1) 9899451b44SJordan Rupprecht thread = self.process.GetThreadAtIndex(0) 9999451b44SJordan Rupprecht 10099451b44SJordan Rupprecht pc_list = [ 0x00164d14, 0x00167c79, 0x00167e6d, 0x7510336a, 0x77759882, 0x77759855] 10199451b44SJordan Rupprecht 10299451b44SJordan Rupprecht self.assertEqual(thread.GetNumFrames(), len(pc_list)) 10399451b44SJordan Rupprecht for i in range(len(pc_list)): 10499451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(i) 10599451b44SJordan Rupprecht self.assertTrue(frame.IsValid()) 10699451b44SJordan Rupprecht self.assertEqual(frame.GetPC(), pc_list[i]) 10799451b44SJordan Rupprecht self.assertTrue(frame.GetModule().IsValid()) 10899451b44SJordan Rupprecht 10999451b44SJordan Rupprecht @skipUnlessWindows # Minidump saving works only on windows 11099451b44SJordan Rupprecht def test_deeper_stack_in_mini_dump(self): 11199451b44SJordan Rupprecht """Test that we can examine a more interesting stack in a mini dump.""" 11299451b44SJordan Rupprecht self.build() 11399451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 11499451b44SJordan Rupprecht core = self.getBuildArtifact("core.dmp") 11599451b44SJordan Rupprecht try: 11699451b44SJordan Rupprecht # Set a breakpoint and capture a mini dump. 11799451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 11899451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName("bar") 11999451b44SJordan Rupprecht process = target.LaunchSimple( 12099451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 121*47c4c6a7SDave Lee self.assertState(process.GetState(), lldb.eStateStopped) 12299451b44SJordan Rupprecht self.assertTrue(process.SaveCore(core)) 12399451b44SJordan Rupprecht self.assertTrue(os.path.isfile(core)) 124779bbbf2SDave Lee self.assertSuccess(process.Kill()) 12599451b44SJordan Rupprecht 12699451b44SJordan Rupprecht # Launch with the mini dump, and inspect the stack. 12799451b44SJordan Rupprecht target = self.dbg.CreateTarget(None) 12899451b44SJordan Rupprecht process = target.LoadCore(core) 12999451b44SJordan Rupprecht thread = process.GetThreadAtIndex(0) 13099451b44SJordan Rupprecht 13199451b44SJordan Rupprecht expected_stack = {0: 'bar', 1: 'foo', 2: 'main'} 13299451b44SJordan Rupprecht self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack)) 13399451b44SJordan Rupprecht for index, name in iteritems(expected_stack): 13499451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(index) 13599451b44SJordan Rupprecht self.assertTrue(frame.IsValid()) 13699451b44SJordan Rupprecht function_name = frame.GetFunctionName() 1373cc37622SDave Lee self.assertIn(name, function_name) 13899451b44SJordan Rupprecht 13999451b44SJordan Rupprecht finally: 14099451b44SJordan Rupprecht # Clean up the mini dump file. 14199451b44SJordan Rupprecht self.assertTrue(self.dbg.DeleteTarget(target)) 14299451b44SJordan Rupprecht if (os.path.isfile(core)): 14399451b44SJordan Rupprecht os.unlink(core) 14499451b44SJordan Rupprecht 14599451b44SJordan Rupprecht @skipUnlessWindows # Minidump saving works only on windows 14699451b44SJordan Rupprecht def test_local_variables_in_mini_dump(self): 14799451b44SJordan Rupprecht """Test that we can examine local variables in a mini dump.""" 14899451b44SJordan Rupprecht self.build() 14999451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 15099451b44SJordan Rupprecht core = self.getBuildArtifact("core.dmp") 15199451b44SJordan Rupprecht try: 15299451b44SJordan Rupprecht # Set a breakpoint and capture a mini dump. 15399451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 15499451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName("bar") 15599451b44SJordan Rupprecht process = target.LaunchSimple( 15699451b44SJordan Rupprecht None, None, self.get_process_working_directory()) 157*47c4c6a7SDave Lee self.assertState(process.GetState(), lldb.eStateStopped) 15899451b44SJordan Rupprecht self.assertTrue(process.SaveCore(core)) 15999451b44SJordan Rupprecht self.assertTrue(os.path.isfile(core)) 160779bbbf2SDave Lee self.assertSuccess(process.Kill()) 16199451b44SJordan Rupprecht 16299451b44SJordan Rupprecht # Launch with the mini dump, and inspect a local variable. 16399451b44SJordan Rupprecht target = self.dbg.CreateTarget(None) 16499451b44SJordan Rupprecht process = target.LoadCore(core) 16599451b44SJordan Rupprecht thread = process.GetThreadAtIndex(0) 16699451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(0) 16799451b44SJordan Rupprecht value = frame.EvaluateExpression('x') 16899451b44SJordan Rupprecht self.assertEqual(value.GetValueAsSigned(), 3) 16999451b44SJordan Rupprecht 17099451b44SJordan Rupprecht finally: 17199451b44SJordan Rupprecht # Clean up the mini dump file. 17299451b44SJordan Rupprecht self.assertTrue(self.dbg.DeleteTarget(target)) 17399451b44SJordan Rupprecht if (os.path.isfile(core)): 17499451b44SJordan Rupprecht os.unlink(core) 175