1""" 2Test NetBSD core file debugging. 3""" 4 5import signal 6import os 7 8import lldb 9from lldbsuite.test.decorators import * 10from lldbsuite.test.lldbtest import * 11from lldbsuite.test import lldbutil 12 13 14class NetBSDCoreCommonTestCase(TestBase): 15 NO_DEBUG_INFO_TESTCASE = True 16 17 def check_memory_regions(self, process, region_count): 18 region_list = process.GetMemoryRegions() 19 self.assertEqual(region_list.GetSize(), region_count) 20 21 region = lldb.SBMemoryRegionInfo() 22 23 # Check we have the right number of regions. 24 self.assertEqual(region_list.GetSize(), region_count) 25 26 # Check that getting a region beyond the last in the list fails. 27 self.assertFalse(region_list.GetMemoryRegionAtIndex(region_count, region)) 28 29 # Check each region is valid. 30 for i in range(region_list.GetSize()): 31 # Check we can actually get this region. 32 self.assertTrue(region_list.GetMemoryRegionAtIndex(i, region)) 33 34 # Every region in the list should be mapped. 35 self.assertTrue(region.IsMapped()) 36 37 # Test the address at the start of a region returns it's enclosing 38 # region. 39 begin_address = region.GetRegionBase() 40 region_at_begin = lldb.SBMemoryRegionInfo() 41 error = process.GetMemoryRegionInfo(begin_address, region_at_begin) 42 self.assertEqual(region, region_at_begin) 43 44 # Test an address in the middle of a region returns it's enclosing 45 # region. 46 middle_address = (region.GetRegionBase() + region.GetRegionEnd()) // 2 47 region_at_middle = lldb.SBMemoryRegionInfo() 48 error = process.GetMemoryRegionInfo(middle_address, region_at_middle) 49 self.assertEqual(region, region_at_middle) 50 51 # Test the address at the end of a region returns it's enclosing 52 # region. 53 end_address = region.GetRegionEnd() - 1 54 region_at_end = lldb.SBMemoryRegionInfo() 55 error = process.GetMemoryRegionInfo(end_address, region_at_end) 56 self.assertEqual(region, region_at_end) 57 58 # Check that quering the end address does not return this region but 59 # the next one. 60 next_region = lldb.SBMemoryRegionInfo() 61 error = process.GetMemoryRegionInfo(region.GetRegionEnd(), next_region) 62 self.assertNotEqual(region, next_region) 63 self.assertEqual(region.GetRegionEnd(), next_region.GetRegionBase()) 64 65 # Check that query beyond the last region returns an unmapped region 66 # that ends at LLDB_INVALID_ADDRESS 67 last_region = lldb.SBMemoryRegionInfo() 68 region_list.GetMemoryRegionAtIndex(region_count - 1, last_region) 69 end_region = lldb.SBMemoryRegionInfo() 70 error = process.GetMemoryRegionInfo(last_region.GetRegionEnd(), end_region) 71 self.assertFalse(end_region.IsMapped()) 72 self.assertEqual(last_region.GetRegionEnd(), end_region.GetRegionBase()) 73 self.assertEqual(end_region.GetRegionEnd(), lldb.LLDB_INVALID_ADDRESS) 74 75 def check_state(self, process): 76 with open(os.devnull) as devnul: 77 # sanitize test output 78 self.dbg.SetOutputFileHandle(devnul, False) 79 self.dbg.SetErrorFileHandle(devnul, False) 80 81 self.assertTrue(process.is_stopped) 82 83 # Process.Continue 84 error = process.Continue() 85 self.assertFalse(error.Success()) 86 self.assertTrue(process.is_stopped) 87 88 # Thread.StepOut 89 thread = process.GetSelectedThread() 90 thread.StepOut() 91 self.assertTrue(process.is_stopped) 92 93 # command line 94 self.dbg.HandleCommand("s") 95 self.assertTrue(process.is_stopped) 96 self.dbg.HandleCommand("c") 97 self.assertTrue(process.is_stopped) 98 99 # restore file handles 100 self.dbg.SetOutputFileHandle(None, False) 101 self.dbg.SetErrorFileHandle(None, False) 102 103 def check_backtrace(self, thread, filename, backtrace): 104 self.assertGreaterEqual(thread.GetNumFrames(), len(backtrace)) 105 src = filename.rpartition(".")[0] + ".c" 106 for i in range(len(backtrace)): 107 frame = thread.GetFrameAtIndex(i) 108 self.assertTrue(frame) 109 if not backtrace[i].startswith("_"): 110 self.assertEqual(frame.GetFunctionName(), backtrace[i]) 111 self.assertEqual( 112 frame.GetLineEntry().GetLine(), 113 line_number(src, "Frame " + backtrace[i]), 114 ) 115 self.assertEqual( 116 frame.FindVariable("F").GetValueAsUnsigned(), ord(backtrace[i][0]) 117 ) 118 119 def do_test(self, filename, pid, region_count): 120 target = self.dbg.CreateTarget(filename) 121 process = target.LoadCore(filename + ".core") 122 123 self.assertTrue(process, PROCESS_IS_VALID) 124 self.assertEqual(process.GetNumThreads(), self.THREAD_COUNT) 125 self.assertEqual(process.GetProcessID(), pid) 126 127 self.check_state(process) 128 129 self.check_stack(process, pid, filename) 130 131 self.check_memory_regions(process, region_count) 132 133 self.dbg.DeleteTarget(target) 134 135 136class NetBSD1LWPCoreTestCase(NetBSDCoreCommonTestCase): 137 THREAD_COUNT = 1 138 139 def check_stack(self, process, pid, filename): 140 thread = process.GetSelectedThread() 141 self.assertTrue(thread) 142 self.assertEqual(thread.GetThreadID(), 1) 143 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal) 144 self.assertEqual(thread.GetStopReasonDataCount(), 1) 145 self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) 146 backtrace = ["bar", "foo", "main"] 147 self.check_backtrace(thread, filename, backtrace) 148 149 @skipIfLLVMTargetMissing("AArch64") 150 def test_aarch64_single_threaded(self): 151 """Test single-threaded aarch64 core dump.""" 152 self.do_test("1lwp_SIGSEGV.aarch64", pid=8339, region_count=32) 153 154 @skipIfLLVMTargetMissing("X86") 155 def test_amd64_single_threaded(self): 156 """Test single-threaded amd64 core dump.""" 157 self.do_test("1lwp_SIGSEGV.amd64", pid=693, region_count=21) 158 159 160class NetBSD2LWPT2CoreTestCase(NetBSDCoreCommonTestCase): 161 THREAD_COUNT = 2 162 163 def check_stack(self, process, pid, filename): 164 thread = process.GetSelectedThread() 165 self.assertTrue(thread) 166 self.assertEqual(thread.GetThreadID(), 2) 167 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal) 168 self.assertEqual(thread.GetStopReasonDataCount(), 1) 169 self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) 170 backtrace = ["bar", "foo", "lwp_main"] 171 self.check_backtrace(thread, filename, backtrace) 172 173 # thread 1 should have no signal 174 thread = process.GetThreadByID(1) 175 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal) 176 self.assertEqual(thread.GetStopReasonDataCount(), 1) 177 self.assertEqual(thread.GetStopReasonDataAtIndex(0), 0) 178 179 @skipIfLLVMTargetMissing("AArch64") 180 def test_aarch64_thread_signaled(self): 181 """Test double-threaded aarch64 core dump where thread 2 is signalled.""" 182 self.do_test("2lwp_t2_SIGSEGV.aarch64", pid=14142, region_count=31) 183 184 @skipIfLLVMTargetMissing("X86") 185 def test_amd64_thread_signaled(self): 186 """Test double-threaded amd64 core dump where thread 2 is signalled.""" 187 self.do_test("2lwp_t2_SIGSEGV.amd64", pid=622, region_count=24) 188 189 190class NetBSD2LWPProcessSigCoreTestCase(NetBSDCoreCommonTestCase): 191 THREAD_COUNT = 2 192 193 def check_stack(self, process, pid, filename): 194 thread = process.GetSelectedThread() 195 self.assertTrue(thread) 196 self.assertEqual(thread.GetThreadID(), 2) 197 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal) 198 self.assertEqual(thread.GetStopReasonDataCount(), 1) 199 self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) 200 backtrace = ["bar", "foo", "lwp_main"] 201 self.check_backtrace(thread, filename, backtrace) 202 203 # thread 1 should have the same signal 204 thread = process.GetThreadByID(1) 205 self.assertStopReason(thread.GetStopReason(), lldb.eStopReasonSignal) 206 self.assertEqual(thread.GetStopReasonDataCount(), 1) 207 self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV) 208 209 @skipIfLLVMTargetMissing("AArch64") 210 def test_aarch64_process_signaled(self): 211 """Test double-threaded aarch64 core dump where process is signalled.""" 212 self.do_test("2lwp_process_SIGSEGV.aarch64", pid=1403, region_count=30) 213 214 @skipIfLLVMTargetMissing("X86") 215 def test_amd64_process_signaled(self): 216 """Test double-threaded amd64 core dump where process is signalled.""" 217 self.do_test("2lwp_process_SIGSEGV.amd64", pid=665, region_count=24) 218