199451b44SJordan Rupprecht""" 299451b44SJordan RupprechtTest basics of mini dump debugging. 399451b44SJordan Rupprecht""" 499451b44SJordan Rupprecht 599451b44SJordan Rupprechtimport lldb 699451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 799451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import * 899451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil 999451b44SJordan Rupprecht 1099451b44SJordan Rupprecht 1199451b44SJordan Rupprechtclass MiniDumpTestCase(TestBase): 1299451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 1399451b44SJordan Rupprecht 1499451b44SJordan Rupprecht def test_process_info_in_mini_dump(self): 1599451b44SJordan Rupprecht """Test that lldb can read the process information from the minidump.""" 1699451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 1799451b44SJordan Rupprecht self.dbg.CreateTarget("") 1899451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 1999451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 2099451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 2199451b44SJordan Rupprecht self.assertEqual(self.process.GetNumThreads(), 1) 2299451b44SJordan Rupprecht self.assertEqual(self.process.GetProcessID(), 4440) 2399451b44SJordan Rupprecht 2499451b44SJordan Rupprecht def test_thread_info_in_mini_dump(self): 2599451b44SJordan Rupprecht """Test that lldb can read the thread information from the minidump.""" 2699451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 2799451b44SJordan Rupprecht self.dbg.CreateTarget("") 2899451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 2999451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 3099451b44SJordan Rupprecht # This process crashed due to an access violation (0xc0000005) in its 3199451b44SJordan Rupprecht # one and only thread. 3299451b44SJordan Rupprecht self.assertEqual(self.process.GetNumThreads(), 1) 3399451b44SJordan Rupprecht thread = self.process.GetThreadAtIndex(0) 340f821339SJonas Devlieghere self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonException) 3599451b44SJordan Rupprecht stop_description = thread.GetStopDescription(256) 363cc37622SDave Lee self.assertIn("0xc0000005", stop_description) 3799451b44SJordan Rupprecht 3899451b44SJordan Rupprecht def test_modules_in_mini_dump(self): 3999451b44SJordan Rupprecht """Test that lldb can read the list of modules from the minidump.""" 4099451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 4199451b44SJordan Rupprecht self.dbg.CreateTarget("") 4299451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 4399451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 4499451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 4599451b44SJordan Rupprecht expected_modules = [ 4699451b44SJordan Rupprecht { 47*2238dcc3SJonas Devlieghere "filename": r"C:\Users\amccarth\Documents\Visual Studio 2013\Projects\fizzbuzz\Debug\fizzbuzz.exe", 48*2238dcc3SJonas Devlieghere "uuid": "0F45B791-9A96-46F9-BF8F-2D6076EA421A-00000011", 4999451b44SJordan Rupprecht }, 5099451b44SJordan Rupprecht { 51*2238dcc3SJonas Devlieghere "filename": r"C:\Windows\SysWOW64\ntdll.dll", 52*2238dcc3SJonas Devlieghere "uuid": "BBB0846A-402C-4052-A16B-67650BBFE6B0-00000002", 5399451b44SJordan Rupprecht }, 5499451b44SJordan Rupprecht { 55*2238dcc3SJonas Devlieghere "filename": r"C:\Windows\SysWOW64\kernel32.dll", 56*2238dcc3SJonas Devlieghere "uuid": "E5CB7E1B-005E-4113-AB98-98D6913B52D8-00000002", 5799451b44SJordan Rupprecht }, 5899451b44SJordan Rupprecht { 59*2238dcc3SJonas Devlieghere "filename": r"C:\Windows\SysWOW64\KERNELBASE.dll", 60*2238dcc3SJonas Devlieghere "uuid": "0BF95241-CB0D-4BD4-AC5D-186A6452E522-00000001", 6199451b44SJordan Rupprecht }, 6299451b44SJordan Rupprecht { 63*2238dcc3SJonas Devlieghere "filename": r"C:\Windows\System32\MSVCP120D.dll", 64*2238dcc3SJonas Devlieghere "uuid": "3C05516E-57E7-40EB-8D3F-9722C5BD80DD-00000001", 6599451b44SJordan Rupprecht }, 6699451b44SJordan Rupprecht { 67*2238dcc3SJonas Devlieghere "filename": r"C:\Windows\System32\MSVCR120D.dll", 68*2238dcc3SJonas Devlieghere "uuid": "6382FB86-46C4-4046-AE42-8D97B3F91FF2-00000001", 6999451b44SJordan Rupprecht }, 7099451b44SJordan Rupprecht ] 7199451b44SJordan Rupprecht self.assertEqual(self.target.GetNumModules(), len(expected_modules)) 7299451b44SJordan Rupprecht for module, expected in zip(self.target.modules, expected_modules): 7399451b44SJordan Rupprecht self.assertTrue(module.IsValid()) 74*2238dcc3SJonas Devlieghere self.assertEqual(module.file.fullpath, expected["filename"]) 75*2238dcc3SJonas Devlieghere self.assertEqual(module.GetUUIDString(), expected["uuid"]) 7699451b44SJordan Rupprecht 7799451b44SJordan Rupprecht def test_breakpad_uuid_matching(self): 7899451b44SJordan Rupprecht """Test that the uuid computation algorithms in minidump and breakpad 7999451b44SJordan Rupprecht files match.""" 8099451b44SJordan Rupprecht self.target = self.dbg.CreateTarget("") 8199451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 8299451b44SJordan Rupprecht self.assertTrue(self.process, PROCESS_IS_VALID) 83*2238dcc3SJonas Devlieghere self.expect( 84*2238dcc3SJonas Devlieghere "target symbols add fizzbuzz.syms", 85*2238dcc3SJonas Devlieghere substrs=[ 86*2238dcc3SJonas Devlieghere "symbol file", 87*2238dcc3SJonas Devlieghere "fizzbuzz.syms", 88*2238dcc3SJonas Devlieghere "has been added to", 89*2238dcc3SJonas Devlieghere "fizzbuzz.exe", 90*2238dcc3SJonas Devlieghere ], 91*2238dcc3SJonas Devlieghere ), 9299451b44SJordan Rupprecht self.assertTrue(self.target.modules[0].FindSymbol("main")) 9399451b44SJordan Rupprecht 9499451b44SJordan Rupprecht @skipIfLLVMTargetMissing("X86") 9599451b44SJordan Rupprecht def test_stack_info_in_mini_dump(self): 9699451b44SJordan Rupprecht """Test that we can see a trivial stack in a VS-generate mini dump.""" 9799451b44SJordan Rupprecht # target create -c fizzbuzz_no_heap.dmp 9899451b44SJordan Rupprecht self.dbg.CreateTarget("") 9999451b44SJordan Rupprecht self.target = self.dbg.GetSelectedTarget() 10099451b44SJordan Rupprecht self.process = self.target.LoadCore("fizzbuzz_no_heap.dmp") 10199451b44SJordan Rupprecht self.assertEqual(self.process.GetNumThreads(), 1) 10299451b44SJordan Rupprecht thread = self.process.GetThreadAtIndex(0) 10399451b44SJordan Rupprecht 104*2238dcc3SJonas Devlieghere pc_list = [ 105*2238dcc3SJonas Devlieghere 0x00164D14, 106*2238dcc3SJonas Devlieghere 0x00167C79, 107*2238dcc3SJonas Devlieghere 0x00167E6D, 108*2238dcc3SJonas Devlieghere 0x7510336A, 109*2238dcc3SJonas Devlieghere 0x77759882, 110*2238dcc3SJonas Devlieghere 0x77759855, 111*2238dcc3SJonas Devlieghere ] 11299451b44SJordan Rupprecht 11399451b44SJordan Rupprecht self.assertEqual(thread.GetNumFrames(), len(pc_list)) 11499451b44SJordan Rupprecht for i in range(len(pc_list)): 11599451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(i) 11699451b44SJordan Rupprecht self.assertTrue(frame.IsValid()) 11799451b44SJordan Rupprecht self.assertEqual(frame.GetPC(), pc_list[i]) 11899451b44SJordan Rupprecht self.assertTrue(frame.GetModule().IsValid()) 11999451b44SJordan Rupprecht 12099451b44SJordan Rupprecht @skipUnlessWindows # Minidump saving works only on windows 12199451b44SJordan Rupprecht def test_deeper_stack_in_mini_dump(self): 12299451b44SJordan Rupprecht """Test that we can examine a more interesting stack in a mini dump.""" 12399451b44SJordan Rupprecht self.build() 12499451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 12599451b44SJordan Rupprecht core = self.getBuildArtifact("core.dmp") 12699451b44SJordan Rupprecht try: 12799451b44SJordan Rupprecht # Set a breakpoint and capture a mini dump. 12899451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 12999451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName("bar") 13099451b44SJordan Rupprecht process = target.LaunchSimple( 131*2238dcc3SJonas Devlieghere None, None, self.get_process_working_directory() 132*2238dcc3SJonas Devlieghere ) 13347c4c6a7SDave Lee self.assertState(process.GetState(), lldb.eStateStopped) 13499451b44SJordan Rupprecht self.assertTrue(process.SaveCore(core)) 13599451b44SJordan Rupprecht self.assertTrue(os.path.isfile(core)) 136779bbbf2SDave Lee self.assertSuccess(process.Kill()) 13799451b44SJordan Rupprecht 13899451b44SJordan Rupprecht # Launch with the mini dump, and inspect the stack. 13999451b44SJordan Rupprecht target = self.dbg.CreateTarget(None) 14099451b44SJordan Rupprecht process = target.LoadCore(core) 14199451b44SJordan Rupprecht thread = process.GetThreadAtIndex(0) 14299451b44SJordan Rupprecht 143*2238dcc3SJonas Devlieghere expected_stack = {0: "bar", 1: "foo", 2: "main"} 14499451b44SJordan Rupprecht self.assertGreaterEqual(thread.GetNumFrames(), len(expected_stack)) 14556f9cfe3SDave Lee for index, name in expected_stack.items(): 14699451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(index) 14799451b44SJordan Rupprecht self.assertTrue(frame.IsValid()) 14899451b44SJordan Rupprecht function_name = frame.GetFunctionName() 1493cc37622SDave Lee self.assertIn(name, function_name) 15099451b44SJordan Rupprecht 15199451b44SJordan Rupprecht finally: 15299451b44SJordan Rupprecht # Clean up the mini dump file. 15399451b44SJordan Rupprecht self.assertTrue(self.dbg.DeleteTarget(target)) 154*2238dcc3SJonas Devlieghere if os.path.isfile(core): 15599451b44SJordan Rupprecht os.unlink(core) 15699451b44SJordan Rupprecht 15799451b44SJordan Rupprecht @skipUnlessWindows # Minidump saving works only on windows 15899451b44SJordan Rupprecht def test_local_variables_in_mini_dump(self): 15999451b44SJordan Rupprecht """Test that we can examine local variables in a mini dump.""" 16099451b44SJordan Rupprecht self.build() 16199451b44SJordan Rupprecht exe = self.getBuildArtifact("a.out") 16299451b44SJordan Rupprecht core = self.getBuildArtifact("core.dmp") 16399451b44SJordan Rupprecht try: 16499451b44SJordan Rupprecht # Set a breakpoint and capture a mini dump. 16599451b44SJordan Rupprecht target = self.dbg.CreateTarget(exe) 16699451b44SJordan Rupprecht breakpoint = target.BreakpointCreateByName("bar") 16799451b44SJordan Rupprecht process = target.LaunchSimple( 168*2238dcc3SJonas Devlieghere None, None, self.get_process_working_directory() 169*2238dcc3SJonas Devlieghere ) 17047c4c6a7SDave Lee self.assertState(process.GetState(), lldb.eStateStopped) 17199451b44SJordan Rupprecht self.assertTrue(process.SaveCore(core)) 17299451b44SJordan Rupprecht self.assertTrue(os.path.isfile(core)) 173779bbbf2SDave Lee self.assertSuccess(process.Kill()) 17499451b44SJordan Rupprecht 17599451b44SJordan Rupprecht # Launch with the mini dump, and inspect a local variable. 17699451b44SJordan Rupprecht target = self.dbg.CreateTarget(None) 17799451b44SJordan Rupprecht process = target.LoadCore(core) 17899451b44SJordan Rupprecht thread = process.GetThreadAtIndex(0) 17999451b44SJordan Rupprecht frame = thread.GetFrameAtIndex(0) 180*2238dcc3SJonas Devlieghere value = frame.EvaluateExpression("x") 18199451b44SJordan Rupprecht self.assertEqual(value.GetValueAsSigned(), 3) 18299451b44SJordan Rupprecht 18399451b44SJordan Rupprecht finally: 18499451b44SJordan Rupprecht # Clean up the mini dump file. 18599451b44SJordan Rupprecht self.assertTrue(self.dbg.DeleteTarget(target)) 186*2238dcc3SJonas Devlieghere if os.path.isfile(core): 18799451b44SJordan Rupprecht os.unlink(core) 188