1""" 2Test saving a mini dump. 3""" 4 5import os 6import lldb 7from lldbsuite.test.decorators import * 8from lldbsuite.test.lldbtest import * 9from lldbsuite.test import lldbutil 10 11 12class ProcessSaveCoreMinidumpTestCase(TestBase): 13 def verify_core_file( 14 self, 15 core_path, 16 expected_pid, 17 expected_modules, 18 expected_threads, 19 stacks_to_sps_map, 20 stacks_to_registers_map, 21 ): 22 # To verify, we'll launch with the mini dump 23 target = self.dbg.CreateTarget(None) 24 process = target.LoadCore(core_path) 25 26 # check if the core is in desired state 27 self.assertTrue(process, PROCESS_IS_VALID) 28 self.assertTrue(process.GetProcessInfo().IsValid()) 29 self.assertEqual(process.GetProcessInfo().GetProcessID(), expected_pid) 30 self.assertNotEqual(target.GetTriple().find("linux"), -1) 31 self.assertTrue(target.GetNumModules(), len(expected_modules)) 32 self.assertEqual(process.GetNumThreads(), len(expected_threads)) 33 34 for module, expected in zip(target.modules, expected_modules): 35 self.assertTrue(module.IsValid()) 36 module_file_name = module.GetFileSpec().GetFilename() 37 expected_file_name = expected.GetFileSpec().GetFilename() 38 # skip kernel virtual dynamic shared objects 39 if "vdso" in expected_file_name: 40 continue 41 self.assertEqual(module_file_name, expected_file_name) 42 self.assertEqual(module.GetUUIDString(), expected.GetUUIDString()) 43 44 red_zone = process.GetTarget().GetStackRedZoneSize() 45 for thread_idx in range(process.GetNumThreads()): 46 thread = process.GetThreadAtIndex(thread_idx) 47 self.assertTrue(thread.IsValid()) 48 thread_id = thread.GetThreadID() 49 self.assertIn(thread_id, expected_threads) 50 frame = thread.GetFrameAtIndex(0) 51 sp_region = lldb.SBMemoryRegionInfo() 52 sp = frame.GetSP() 53 err = process.GetMemoryRegionInfo(sp, sp_region) 54 self.assertTrue(err.Success(), err.GetCString()) 55 error = lldb.SBError() 56 # Ensure thread_id is in the saved map 57 self.assertIn(thread_id, stacks_to_sps_map) 58 # Ensure the SP is correct 59 self.assertEqual(stacks_to_sps_map[thread_id], sp) 60 # Try to read at the end of the stack red zone and succeed 61 process.ReadMemory(sp - red_zone, 1, error) 62 self.assertTrue(error.Success(), error.GetCString()) 63 # Try to read just past the red zone and fail 64 process.ReadMemory(sp - red_zone - 1, 1, error) 65 self.assertTrue(error.Fail(), "No failure when reading past the red zone") 66 # Verify the registers are the same 67 self.assertIn(thread_id, stacks_to_registers_map) 68 register_val_list = stacks_to_registers_map[thread_id] 69 frame_register_list = frame.GetRegisters() 70 # explicitly verify we collected fs and gs base for x86_64 71 explicit_registers = ["fs_base", "gs_base"] 72 for reg in explicit_registers: 73 register = frame_register_list.GetFirstValueByName(reg) 74 self.assertNotEqual(None, register) 75 self.assertEqual( 76 register.GetValueAsUnsigned(), 77 stacks_to_registers_map[thread_id] 78 .GetFirstValueByName("fs_base") 79 .GetValueAsUnsigned(), 80 ) 81 82 for x in register_val_list: 83 self.assertEqual( 84 x.GetValueAsUnsigned(), 85 frame_register_list.GetFirstValueByName( 86 x.GetName() 87 ).GetValueAsUnsigned(), 88 ) 89 90 self.dbg.DeleteTarget(target) 91 92 @skipUnlessArch("x86_64") 93 @skipUnlessPlatform(["linux"]) 94 def test_save_linux_mini_dump(self): 95 """Test that we can save a Linux mini dump.""" 96 97 self.build() 98 exe = self.getBuildArtifact("a.out") 99 core_stack = self.getBuildArtifact("core.stack.dmp") 100 core_dirty = self.getBuildArtifact("core.dirty.dmp") 101 core_full = self.getBuildArtifact("core.full.dmp") 102 core_sb_stack = self.getBuildArtifact("core_sb.stack.dmp") 103 core_sb_dirty = self.getBuildArtifact("core_sb.dirty.dmp") 104 core_sb_full = self.getBuildArtifact("core_sb.full.dmp") 105 try: 106 target = self.dbg.CreateTarget(exe) 107 process = target.LaunchSimple( 108 None, None, self.get_process_working_directory() 109 ) 110 self.assertState(process.GetState(), lldb.eStateStopped) 111 112 # get neccessary data for the verification phase 113 process_info = process.GetProcessInfo() 114 expected_pid = process_info.GetProcessID() if process_info.IsValid() else -1 115 expected_number_of_modules = target.GetNumModules() 116 expected_modules = target.modules 117 expected_number_of_threads = process.GetNumThreads() 118 expected_threads = [] 119 stacks_to_sp_map = {} 120 stacks_to_registers_map = {} 121 122 for thread_idx in range(process.GetNumThreads()): 123 thread = process.GetThreadAtIndex(thread_idx) 124 thread_id = thread.GetThreadID() 125 expected_threads.append(thread_id) 126 stacks_to_sp_map[thread_id] = thread.GetFrameAtIndex(0).GetSP() 127 stacks_to_registers_map[thread_id] = thread.GetFrameAtIndex( 128 0 129 ).GetRegisters() 130 131 # save core and, kill process and verify corefile existence 132 base_command = "process save-core --plugin-name=minidump " 133 self.runCmd(base_command + " --style=stack '%s'" % (core_stack)) 134 self.assertTrue(os.path.isfile(core_stack)) 135 self.verify_core_file( 136 core_stack, 137 expected_pid, 138 expected_modules, 139 expected_threads, 140 stacks_to_sp_map, 141 stacks_to_registers_map, 142 ) 143 144 self.runCmd(base_command + " --style=modified-memory '%s'" % (core_dirty)) 145 self.assertTrue(os.path.isfile(core_dirty)) 146 self.verify_core_file( 147 core_dirty, 148 expected_pid, 149 expected_modules, 150 expected_threads, 151 stacks_to_sp_map, 152 stacks_to_registers_map, 153 ) 154 155 self.runCmd(base_command + " --style=full '%s'" % (core_full)) 156 self.assertTrue(os.path.isfile(core_full)) 157 self.verify_core_file( 158 core_full, 159 expected_pid, 160 expected_modules, 161 expected_threads, 162 stacks_to_sp_map, 163 stacks_to_registers_map, 164 ) 165 166 options = lldb.SBSaveCoreOptions() 167 core_sb_stack_spec = lldb.SBFileSpec(core_sb_stack) 168 options.SetOutputFile(core_sb_stack_spec) 169 options.SetPluginName("minidump") 170 options.SetStyle(lldb.eSaveCoreStackOnly) 171 # validate saving via SBProcess 172 error = process.SaveCore(options) 173 self.assertTrue(error.Success()) 174 self.assertTrue(os.path.isfile(core_sb_stack)) 175 self.verify_core_file( 176 core_sb_stack, 177 expected_pid, 178 expected_modules, 179 expected_threads, 180 stacks_to_sp_map, 181 stacks_to_registers_map, 182 ) 183 184 options = lldb.SBSaveCoreOptions() 185 core_sb_dirty_spec = lldb.SBFileSpec(core_sb_dirty) 186 options.SetOutputFile(core_sb_dirty_spec) 187 options.SetPluginName("minidump") 188 options.SetStyle(lldb.eSaveCoreDirtyOnly) 189 error = process.SaveCore(options) 190 self.assertTrue(error.Success()) 191 self.assertTrue(os.path.isfile(core_sb_dirty)) 192 self.verify_core_file( 193 core_sb_dirty, 194 expected_pid, 195 expected_modules, 196 expected_threads, 197 stacks_to_sp_map, 198 stacks_to_registers_map, 199 ) 200 201 # Minidump can now save full core files, but they will be huge and 202 # they might cause this test to timeout. 203 options = lldb.SBSaveCoreOptions() 204 core_sb_full_spec = lldb.SBFileSpec(core_sb_full) 205 options.SetOutputFile(core_sb_full_spec) 206 options.SetPluginName("minidump") 207 options.SetStyle(lldb.eSaveCoreFull) 208 error = process.SaveCore(options) 209 self.assertTrue(error.Success()) 210 self.assertTrue(os.path.isfile(core_sb_full)) 211 self.verify_core_file( 212 core_sb_full, 213 expected_pid, 214 expected_modules, 215 expected_threads, 216 stacks_to_sp_map, 217 stacks_to_registers_map, 218 ) 219 220 self.assertSuccess(process.Kill()) 221 finally: 222 # Clean up the mini dump file. 223 self.assertTrue(self.dbg.DeleteTarget(target)) 224 if os.path.isfile(core_stack): 225 os.unlink(core_stack) 226 if os.path.isfile(core_dirty): 227 os.unlink(core_dirty) 228 if os.path.isfile(core_full): 229 os.unlink(core_full) 230 if os.path.isfile(core_sb_stack): 231 os.unlink(core_sb_stack) 232 if os.path.isfile(core_sb_dirty): 233 os.unlink(core_sb_dirty) 234 if os.path.isfile(core_sb_full): 235 os.unlink(core_sb_full) 236 237 @skipUnlessArch("x86_64") 238 @skipUnlessPlatform(["linux"]) 239 def test_save_linux_mini_dump_thread_options(self): 240 """Test that we can save a Linux mini dump 241 with a subset of threads""" 242 243 self.build() 244 exe = self.getBuildArtifact("a.out") 245 thread_subset_dmp = self.getBuildArtifact("core.thread.subset.dmp") 246 try: 247 target = self.dbg.CreateTarget(exe) 248 process = target.LaunchSimple( 249 None, None, self.get_process_working_directory() 250 ) 251 self.assertState(process.GetState(), lldb.eStateStopped) 252 253 thread_to_include = process.GetThreadAtIndex(0) 254 options = lldb.SBSaveCoreOptions() 255 thread_subset_spec = lldb.SBFileSpec(thread_subset_dmp) 256 options.AddThread(thread_to_include) 257 options.SetOutputFile(thread_subset_spec) 258 options.SetPluginName("minidump") 259 options.SetStyle(lldb.eSaveCoreStackOnly) 260 error = process.SaveCore(options) 261 self.assertTrue(error.Success()) 262 263 core_target = self.dbg.CreateTarget(None) 264 core_process = core_target.LoadCore(thread_subset_dmp) 265 266 self.assertTrue(core_process, PROCESS_IS_VALID) 267 self.assertEqual(core_process.GetNumThreads(), 1) 268 saved_thread = core_process.GetThreadAtIndex(0) 269 expected_thread = process.GetThreadAtIndex(0) 270 self.assertEqual(expected_thread.GetThreadID(), saved_thread.GetThreadID()) 271 expected_sp = expected_thread.GetFrameAtIndex(0).GetSP() 272 saved_sp = saved_thread.GetFrameAtIndex(0).GetSP() 273 self.assertEqual(expected_sp, saved_sp) 274 expected_region = lldb.SBMemoryRegionInfo() 275 saved_region = lldb.SBMemoryRegionInfo() 276 error = core_process.GetMemoryRegionInfo(saved_sp, saved_region) 277 self.assertTrue(error.Success(), error.GetCString()) 278 error = process.GetMemoryRegionInfo(expected_sp, expected_region) 279 self.assertTrue(error.Success(), error.GetCString()) 280 self.assertEqual( 281 expected_region.GetRegionBase(), saved_region.GetRegionBase() 282 ) 283 self.assertEqual( 284 expected_region.GetRegionEnd(), saved_region.GetRegionEnd() 285 ) 286 287 finally: 288 self.assertTrue(self.dbg.DeleteTarget(target)) 289 if os.path.isfile(thread_subset_dmp): 290 os.unlink(thread_subset_dmp) 291 292 @skipUnlessArch("x86_64") 293 @skipUnlessPlatform(["linux"]) 294 def test_save_linux_mini_dump_default_options(self): 295 """Test that we can save a Linux mini dump with default SBSaveCoreOptions""" 296 297 self.build() 298 exe = self.getBuildArtifact("a.out") 299 default_value_file = self.getBuildArtifact("core.defaults.dmp") 300 try: 301 target = self.dbg.CreateTarget(exe) 302 process = target.LaunchSimple( 303 None, None, self.get_process_working_directory() 304 ) 305 self.assertState(process.GetState(), lldb.eStateStopped) 306 307 process_info = process.GetProcessInfo() 308 expected_pid = process_info.GetProcessID() if process_info.IsValid() else -1 309 expected_modules = target.modules 310 expected_threads = [] 311 stacks_to_sp_map = {} 312 expected_pid = process.GetProcessInfo().GetProcessID() 313 stacks_to_registers_map = {} 314 315 for thread_idx in range(process.GetNumThreads()): 316 thread = process.GetThreadAtIndex(thread_idx) 317 thread_id = thread.GetThreadID() 318 expected_threads.append(thread_id) 319 stacks_to_sp_map[thread_id] = thread.GetFrameAtIndex(0).GetSP() 320 stacks_to_registers_map[thread_id] = thread.GetFrameAtIndex( 321 0 322 ).GetRegisters() 323 324 # This is almost identical to the single thread test case because 325 # minidump defaults to stacks only, so we want to see if the 326 # default options work as expected. 327 options = lldb.SBSaveCoreOptions() 328 default_value_spec = lldb.SBFileSpec(default_value_file) 329 options.SetOutputFile(default_value_spec) 330 options.SetPluginName("minidump") 331 error = process.SaveCore(options) 332 self.assertTrue(error.Success()) 333 334 self.verify_core_file( 335 default_value_file, 336 expected_pid, 337 expected_modules, 338 expected_threads, 339 stacks_to_sp_map, 340 stacks_to_registers_map, 341 ) 342 343 finally: 344 self.assertTrue(self.dbg.DeleteTarget(target)) 345 if os.path.isfile(default_value_file): 346 os.unlink(default_value_file) 347 348 @skipUnlessArch("x86_64") 349 @skipUnlessPlatform(["linux"]) 350 def test_save_linux_minidump_one_region(self): 351 """Test that we can save a Linux mini dump with one region in sbsavecore regions""" 352 353 self.build() 354 exe = self.getBuildArtifact("a.out") 355 one_region_file = self.getBuildArtifact("core.one_region.dmp") 356 try: 357 target = self.dbg.CreateTarget(exe) 358 process = target.LaunchSimple( 359 None, None, self.get_process_working_directory() 360 ) 361 self.assertState(process.GetState(), lldb.eStateStopped) 362 363 memory_region = lldb.SBMemoryRegionInfo() 364 memory_list = process.GetMemoryRegions() 365 memory_list.GetMemoryRegionAtIndex(0, memory_region) 366 367 # This is almost identical to the single thread test case because 368 # minidump defaults to stacks only, so we want to see if the 369 # default options work as expected. 370 options = lldb.SBSaveCoreOptions() 371 file_spec = lldb.SBFileSpec(one_region_file) 372 options.SetOutputFile(file_spec) 373 options.SetPluginName("minidump") 374 options.AddMemoryRegionToSave(memory_region) 375 options.SetStyle(lldb.eSaveCoreCustomOnly) 376 error = process.SaveCore(options) 377 print(f"Error: {error.GetCString()}") 378 self.assertTrue(error.Success(), error.GetCString()) 379 380 core_target = self.dbg.CreateTarget(None) 381 core_proc = core_target.LoadCore(one_region_file) 382 core_memory_list = core_proc.GetMemoryRegions() 383 # Note because the /proc/pid maps are included on linux, we can't 384 # depend on size for validation, so we'll ensure the first region 385 # is present and then assert we fail on the second. 386 core_memory_region = lldb.SBMemoryRegionInfo() 387 core_memory_list.GetMemoryRegionAtIndex(0, core_memory_region) 388 self.assertEqual( 389 core_memory_region.GetRegionBase(), memory_region.GetRegionBase() 390 ) 391 self.assertEqual( 392 core_memory_region.GetRegionEnd(), memory_region.GetRegionEnd() 393 ) 394 395 region_two = lldb.SBMemoryRegionInfo() 396 core_memory_list.GetMemoryRegionAtIndex(1, region_two) 397 err = lldb.SBError() 398 content = core_proc.ReadMemory(region_two.GetRegionBase(), 1, err) 399 self.assertTrue(err.Fail(), "Should fail to read memory") 400 401 finally: 402 self.assertTrue(self.dbg.DeleteTarget(target)) 403 if os.path.isfile(one_region_file): 404 os.unlink(one_region_file) 405 406 @skipUnlessArch("x86_64") 407 @skipUnlessPlatform(["linux"]) 408 def test_save_minidump_custom_save_style(self): 409 """Test that verifies a custom and unspecified save style fails for 410 containing no data to save""" 411 412 self.build() 413 exe = self.getBuildArtifact("a.out") 414 custom_file = self.getBuildArtifact("core.custom.dmp") 415 try: 416 target = self.dbg.CreateTarget(exe) 417 process = target.LaunchSimple( 418 None, None, self.get_process_working_directory() 419 ) 420 self.assertState(process.GetState(), lldb.eStateStopped) 421 422 options = lldb.SBSaveCoreOptions() 423 options.SetOutputFile(lldb.SBFileSpec(custom_file)) 424 options.SetPluginName("minidump") 425 options.SetStyle(lldb.eSaveCoreCustomOnly) 426 427 error = process.SaveCore(options) 428 self.assertTrue(error.Fail()) 429 self.assertEqual( 430 error.GetCString(), "no valid address ranges found for core style" 431 ) 432 433 finally: 434 self.assertTrue(self.dbg.DeleteTarget(target)) 435 if os.path.isfile(custom_file): 436 os.unlink(custom_file) 437 438 def save_core_with_region(self, process, region_index): 439 try: 440 custom_file = self.getBuildArtifact("core.custom.dmp") 441 memory_region = lldb.SBMemoryRegionInfo() 442 memory_list = process.GetMemoryRegions() 443 memory_list.GetMemoryRegionAtIndex(0, memory_region) 444 options = lldb.SBSaveCoreOptions() 445 options.SetOutputFile(lldb.SBFileSpec(custom_file)) 446 options.SetPluginName("minidump") 447 options.SetStyle(lldb.eSaveCoreFull) 448 449 error = process.SaveCore(options) 450 self.assertTrue(error.Success()) 451 core_target = self.dbg.CreateTarget(None) 452 core_proc = core_target.LoadCore(custom_file) 453 core_memory_list = core_proc.GetMemoryRegions() 454 # proc/pid/ maps are included on linux, so we can't depend on size 455 # for validation, we make a set of all the ranges, 456 # and ensure no duplicates! 457 range_set = set() 458 for x in range(core_memory_list.GetSize()): 459 core_memory_region = lldb.SBMemoryRegionInfo() 460 core_memory_list.GetMemoryRegionAtIndex(x, core_memory_region) 461 mem_tuple = ( 462 core_memory_region.GetRegionBase(), 463 core_memory_region.GetRegionEnd(), 464 ) 465 self.assertTrue( 466 mem_tuple not in range_set, "Duplicate memory region found" 467 ) 468 range_set.add(mem_tuple) 469 finally: 470 if os.path.isfile(custom_file): 471 os.unlink(custom_file) 472 473 @skipUnlessArch("x86_64") 474 @skipUnlessPlatform(["linux"]) 475 def test_save_minidump_custom_save_style_duplicated_regions(self): 476 """Test that verifies a custom and unspecified save style fails for 477 containing no data to save""" 478 479 self.build() 480 exe = self.getBuildArtifact("a.out") 481 try: 482 target = self.dbg.CreateTarget(exe) 483 process = target.LaunchSimple( 484 None, None, self.get_process_working_directory() 485 ) 486 self.assertState(process.GetState(), lldb.eStateStopped) 487 488 memory_list = process.GetMemoryRegions() 489 # Test that we don't duplicate regions, by duplicating regions 490 # at various indices. 491 self.save_core_with_region(process, 0) 492 self.save_core_with_region(process, len(memory_list) - 1) 493 494 finally: 495 self.assertTrue(self.dbg.DeleteTarget(target)) 496 497 @skipUnlessPlatform(["linux"]) 498 def minidump_deleted_on_save_failure(self): 499 """Test that verifies the minidump file is deleted after an error""" 500 501 self.build() 502 exe = self.getBuildArtifact("a.out") 503 try: 504 target = self.dbg.CreateTarget(exe) 505 process = target.LaunchSimple( 506 None, None, self.get_process_working_directory() 507 ) 508 self.assertState(process.GetState(), lldb.eStateStopped) 509 510 custom_file = self.getBuildArtifact("core.should.be.deleted.custom.dmp") 511 options = lldb.SBSaveCoreOptions() 512 options.SetOutputFile(lldb.SBFileSpec(custom_file)) 513 options.SetPluginName("minidump") 514 options.SetStyle(lldb.eSaveCoreCustomOnly) 515 # We set custom only and have no thread list and have no memory. 516 error = process.SaveCore(options) 517 self.assertTrue(error.Fail()) 518 self.assertIn( 519 "no valid address ranges found for core style", error.GetCString() 520 ) 521 self.assertTrue(not os.path.isfile(custom_file)) 522 523 finally: 524 self.assertTrue(self.dbg.DeleteTarget(target)) 525 526 @skipUnlessPlatform(["linux"]) 527 @skipUnlessArch("x86_64") 528 def minidump_saves_fs_base_region(self): 529 """Test that verifies the minidump file saves region for fs_base""" 530 531 self.build() 532 exe = self.getBuildArtifact("a.out") 533 try: 534 target = self.dbg.CreateTarget(exe) 535 process = target.LaunchSimple( 536 None, None, self.get_process_working_directory() 537 ) 538 self.assertState(process.GetState(), lldb.eStateStopped) 539 thread = process.GetThreadAtIndex(0) 540 custom_file = self.getBuildArtifact("core.reg_region.dmp") 541 options = lldb.SBSaveCoreOptions() 542 options.SetOutputFile(lldb.SBFileSpec(custom_file)) 543 options.SetPluginName("minidump") 544 options.SetStyle(lldb.eSaveCoreCustomOnly) 545 options.AddThread(thread) 546 error = process.SaveCore(options) 547 self.assertTrue(error.Success()) 548 549 registers = thread.GetFrameAtIndex(0).GetRegisters() 550 fs_base = registers.GetFirstValueByName("fs_base").GetValueAsUnsigned() 551 self.assertTrue(fs_base != 0) 552 core_target = self.dbg.CreateTarget(None) 553 core_proc = core_target.LoadCore(one_region_file) 554 core_region_list = core_proc.GetMemoryRegions() 555 live_region_list = process.GetMemoryRegions() 556 live_region = lldb.SBMemoryRegionInfo() 557 live_region_list.GetMemoryRegionForAddress(fs_base, live_region) 558 core_region = lldb.SBMemoryRegionInfo() 559 error = core_region_list.GetMemoryRegionForAddress(fs_base, core_region) 560 self.assertTrue(error.Success()) 561 self.assertEqual(live_region, core_region) 562 563 finally: 564 self.assertTrue(self.dbg.DeleteTarget(target)) 565 self.assertTrue(self.dbg.DeleteTarget(core_target)) 566 if os.path.isfile(custom_file): 567 os.unlink(custom_file) 568 569 def minidump_deterministic_difference(self): 570 """Test that verifies that two minidumps produced are identical.""" 571 self.build() 572 exe = self.getBuildArtifact("a.out") 573 try: 574 target = self.dbg.CreateTarget(exe) 575 process = target.LaunchSimple( 576 None, None, self.get_process_working_directory() 577 ) 578 579 core_styles = [ 580 lldb.eSaveCoreStackOnly, 581 lldb.eSaveCoreDirtyOnly, 582 lldb.eSaveCoreFull, 583 ] 584 for style in core_styles: 585 spec_one = lldb.SBFileSpec(self.getBuildArtifact("core.one.dmp")) 586 spec_two = lldb.SBFileSpec(self.getBuildArtifact("core.two.dmp")) 587 options = lldb.SBSaveCoreOptions() 588 options.SetOutputFile(spec_one) 589 options.SetPluginName("minidump") 590 options.SetStyle(style) 591 error = process.SaveCore(options) 592 self.assertTrue(error.Success()) 593 options.SetOutputFile(spec_two) 594 error = process.SaveCore(options) 595 self.assertTrue(error.Success()) 596 597 file_one = None 598 file_two = None 599 with open(spec_one.GetFileName(), mode="rb") as file: 600 file_one = file.read() 601 with open(spec_two.GetFileName(), mode="rb") as file: 602 file_two = file.read() 603 self.assertEqual(file_one, file_two) 604 self.assertTrue(os.unlink(spec_one.GetFileName())) 605 self.assertTrue(os.unlink(spec_two.GetFileName())) 606 finally: 607 self.assertTrue(self.dbg.DeleteTarget(target)) 608 609 @skipUnlessPlatform(["linux"]) 610 @skipUnlessArch("x86_64") 611 def minidump_saves_fs_base_region(self): 612 self.build() 613 exe = self.getBuildArtifact("a.out") 614 try: 615 target = self.dbg.CreateTarget(exe) 616 process = target.LaunchSimple( 617 None, None, self.get_process_working_directory() 618 ) 619 self.assertState(process.GetState(), lldb.eStateStopped) 620 thread = process.GetThreadAtIndex(0) 621 tls_file = self.getBuildArtifact("core.tls.dmp") 622 options = lldb.SBSaveCoreOptions() 623 options.SetOutputFile(lldb.SBFileSpec(tls_file)) 624 options.SetPluginName("minidump") 625 options.SetStyle(lldb.eSaveCoreCustomOnly) 626 options.AddThread(thread) 627 error = process.SaveCore(options) 628 self.assertTrue(error.Success()) 629 core_target = self.dbg.CreateTarget(None) 630 core_proc = core_target.LoadCore(tls_file) 631 frame = core_proc.GetThreadAtIndex(0).GetFrameAtIndex(0) 632 tls_val = frame.FindValue("lf") 633 self.assertEqual(tls_val.GetValueAsUnsigned(), 42) 634 635 except: 636 self.assertTrue(self.dbg.DeleteTarget(target)) 637 if os.path.isfile(tls_file): 638 os.unlink(tls_file) 639