OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2012 the V8 project authors. All rights reserved. | 3 # Copyright 2012 the V8 project authors. All rights reserved. |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 ("cs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), | 289 ("cs", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), |
290 ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), | 290 ("eflags", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), |
291 ("esp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), | 291 ("esp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), |
292 ("ss", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), | 292 ("ss", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_X86_CONTROL)), |
293 # MD_CONTEXT_X86_EXTENDED_REGISTERS. | 293 # MD_CONTEXT_X86_EXTENDED_REGISTERS. |
294 ("extended_registers", | 294 ("extended_registers", |
295 EnableOnFlag(ctypes.c_uint8 * MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE, | 295 EnableOnFlag(ctypes.c_uint8 * MD_CONTEXT_X86_EXTENDED_REGISTERS_SIZE, |
296 MD_CONTEXT_X86_EXTENDED_REGISTERS)) | 296 MD_CONTEXT_X86_EXTENDED_REGISTERS)) |
297 ]) | 297 ]) |
298 | 298 |
| 299 MD_CONTEXT_ARM = 0x40000000 |
| 300 MD_CONTEXT_ARM_INTEGER = (MD_CONTEXT_ARM | 0x00000002) |
| 301 MD_CONTEXT_ARM_FLOATING_POINT = (MD_CONTEXT_ARM | 0x00000004) |
| 302 MD_FLOATINGSAVEAREA_ARM_FPR_COUNT = 32 |
| 303 MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT = 8 |
| 304 |
| 305 MINIDUMP_FLOATING_SAVE_AREA_ARM = Descriptor([ |
| 306 ("fpscr", ctypes.c_uint64), |
| 307 ("regs", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPR_COUNT), |
| 308 ("extra", ctypes.c_uint64 * MD_FLOATINGSAVEAREA_ARM_FPEXTRA_COUNT) |
| 309 ]) |
| 310 |
| 311 MINIDUMP_CONTEXT_ARM = Descriptor([ |
| 312 ("context_flags", ctypes.c_uint32), |
| 313 # MD_CONTEXT_ARM_INTEGER. |
| 314 ("r0", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 315 ("r1", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 316 ("r2", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 317 ("r3", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 318 ("r4", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 319 ("r5", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 320 ("r6", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 321 ("r7", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 322 ("r8", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 323 ("r9", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 324 ("r10", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 325 ("r11", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 326 ("r12", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 327 ("sp", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 328 ("lr", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 329 ("pc", EnableOnFlag(ctypes.c_uint32, MD_CONTEXT_ARM_INTEGER)), |
| 330 ("cpsr", ctypes.c_uint32), |
| 331 ("float_save", EnableOnFlag(MINIDUMP_FLOATING_SAVE_AREA_ARM.ctype, |
| 332 MD_CONTEXT_ARM_FLOATING_POINT)) |
| 333 ]) |
| 334 |
299 MD_CONTEXT_AMD64 = 0x00100000 | 335 MD_CONTEXT_AMD64 = 0x00100000 |
300 MD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001) | 336 MD_CONTEXT_AMD64_CONTROL = (MD_CONTEXT_AMD64 | 0x00000001) |
301 MD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002) | 337 MD_CONTEXT_AMD64_INTEGER = (MD_CONTEXT_AMD64 | 0x00000002) |
302 MD_CONTEXT_AMD64_SEGMENTS = (MD_CONTEXT_AMD64 | 0x00000004) | 338 MD_CONTEXT_AMD64_SEGMENTS = (MD_CONTEXT_AMD64 | 0x00000004) |
303 MD_CONTEXT_AMD64_FLOATING_POINT = (MD_CONTEXT_AMD64 | 0x00000008) | 339 MD_CONTEXT_AMD64_FLOATING_POINT = (MD_CONTEXT_AMD64 | 0x00000008) |
304 MD_CONTEXT_AMD64_DEBUG_REGISTERS = (MD_CONTEXT_AMD64 | 0x00000010) | 340 MD_CONTEXT_AMD64_DEBUG_REGISTERS = (MD_CONTEXT_AMD64 | 0x00000010) |
305 | 341 |
306 MINIDUMP_CONTEXT_AMD64 = Descriptor([ | 342 MINIDUMP_CONTEXT_AMD64 = Descriptor([ |
307 ("p1_home", ctypes.c_uint64), | 343 ("p1_home", ctypes.c_uint64), |
308 ("p2_home", ctypes.c_uint64), | 344 ("p2_home", ctypes.c_uint64), |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 MINIDUMP_MODULE_LIST = Descriptor([ | 458 MINIDUMP_MODULE_LIST = Descriptor([ |
423 ("number_of_modules", ctypes.c_uint32), | 459 ("number_of_modules", ctypes.c_uint32), |
424 ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) | 460 ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) |
425 ]) | 461 ]) |
426 | 462 |
427 MINIDUMP_RAW_SYSTEM_INFO = Descriptor([ | 463 MINIDUMP_RAW_SYSTEM_INFO = Descriptor([ |
428 ("processor_architecture", ctypes.c_uint16) | 464 ("processor_architecture", ctypes.c_uint16) |
429 ]) | 465 ]) |
430 | 466 |
431 MD_CPU_ARCHITECTURE_X86 = 0 | 467 MD_CPU_ARCHITECTURE_X86 = 0 |
| 468 MD_CPU_ARCHITECTURE_ARM = 5 |
432 MD_CPU_ARCHITECTURE_AMD64 = 9 | 469 MD_CPU_ARCHITECTURE_AMD64 = 9 |
433 | 470 |
434 class FuncSymbol: | 471 class FuncSymbol: |
435 def __init__(self, start, size, name): | 472 def __init__(self, start, size, name): |
436 self.start = start | 473 self.start = start |
437 self.end = self.start + size | 474 self.end = self.start + size |
438 self.name = name | 475 self.name = name |
439 | 476 |
440 def __cmp__(self, other): | 477 def __cmp__(self, other): |
441 if isinstance(other, FuncSymbol): | 478 if isinstance(other, FuncSymbol): |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 self.symdir = options.symdir | 511 self.symdir = options.symdir |
475 self.modules_with_symbols = [] | 512 self.modules_with_symbols = [] |
476 self.symbols = [] | 513 self.symbols = [] |
477 | 514 |
478 # Find MDRawSystemInfo stream and determine arch. | 515 # Find MDRawSystemInfo stream and determine arch. |
479 for d in directories: | 516 for d in directories: |
480 if d.stream_type == MD_SYSTEM_INFO_STREAM: | 517 if d.stream_type == MD_SYSTEM_INFO_STREAM: |
481 system_info = MINIDUMP_RAW_SYSTEM_INFO.Read( | 518 system_info = MINIDUMP_RAW_SYSTEM_INFO.Read( |
482 self.minidump, d.location.rva) | 519 self.minidump, d.location.rva) |
483 self.arch = system_info.processor_architecture | 520 self.arch = system_info.processor_architecture |
484 assert self.arch in [MD_CPU_ARCHITECTURE_AMD64, MD_CPU_ARCHITECTURE_X86] | 521 assert self.arch in [MD_CPU_ARCHITECTURE_AMD64, |
| 522 MD_CPU_ARCHITECTURE_ARM, |
| 523 MD_CPU_ARCHITECTURE_X86] |
485 assert not self.arch is None | 524 assert not self.arch is None |
486 | 525 |
487 for d in directories: | 526 for d in directories: |
488 DebugPrint(d) | 527 DebugPrint(d) |
489 if d.stream_type == MD_EXCEPTION_STREAM: | 528 if d.stream_type == MD_EXCEPTION_STREAM: |
490 self.exception = MINIDUMP_EXCEPTION_STREAM.Read( | 529 self.exception = MINIDUMP_EXCEPTION_STREAM.Read( |
491 self.minidump, d.location.rva) | 530 self.minidump, d.location.rva) |
492 DebugPrint(self.exception) | 531 DebugPrint(self.exception) |
493 if self.arch == MD_CPU_ARCHITECTURE_X86: | 532 if self.arch == MD_CPU_ARCHITECTURE_X86: |
494 self.exception_context = MINIDUMP_CONTEXT_X86.Read( | 533 self.exception_context = MINIDUMP_CONTEXT_X86.Read( |
495 self.minidump, self.exception.thread_context.rva) | 534 self.minidump, self.exception.thread_context.rva) |
496 elif self.arch == MD_CPU_ARCHITECTURE_AMD64: | 535 elif self.arch == MD_CPU_ARCHITECTURE_AMD64: |
497 self.exception_context = MINIDUMP_CONTEXT_AMD64.Read( | 536 self.exception_context = MINIDUMP_CONTEXT_AMD64.Read( |
498 self.minidump, self.exception.thread_context.rva) | 537 self.minidump, self.exception.thread_context.rva) |
| 538 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 539 self.exception_context = MINIDUMP_CONTEXT_ARM.Read( |
| 540 self.minidump, self.exception.thread_context.rva) |
499 DebugPrint(self.exception_context) | 541 DebugPrint(self.exception_context) |
500 elif d.stream_type == MD_THREAD_LIST_STREAM: | 542 elif d.stream_type == MD_THREAD_LIST_STREAM: |
501 thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva) | 543 thread_list = MINIDUMP_THREAD_LIST.Read(self.minidump, d.location.rva) |
502 assert ctypes.sizeof(thread_list) == d.location.data_size | 544 assert ctypes.sizeof(thread_list) == d.location.data_size |
503 DebugPrint(thread_list) | 545 DebugPrint(thread_list) |
504 for thread in thread_list.threads: | 546 for thread in thread_list.threads: |
505 DebugPrint(thread) | 547 DebugPrint(thread) |
506 self.thread_map[thread.id] = thread | 548 self.thread_map[thread.id] = thread |
507 elif d.stream_type == MD_MODULE_LIST_STREAM: | 549 elif d.stream_type == MD_MODULE_LIST_STREAM: |
508 assert self.module_list is None | 550 assert self.module_list is None |
(...skipping 25 matching lines...) Expand all Loading... |
534 location = self.FindLocation(address) | 576 location = self.FindLocation(address) |
535 return ctypes.c_uint32.from_buffer(self.minidump, location).value | 577 return ctypes.c_uint32.from_buffer(self.minidump, location).value |
536 | 578 |
537 def ReadU64(self, address): | 579 def ReadU64(self, address): |
538 location = self.FindLocation(address) | 580 location = self.FindLocation(address) |
539 return ctypes.c_uint64.from_buffer(self.minidump, location).value | 581 return ctypes.c_uint64.from_buffer(self.minidump, location).value |
540 | 582 |
541 def ReadUIntPtr(self, address): | 583 def ReadUIntPtr(self, address): |
542 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 584 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
543 return self.ReadU64(address) | 585 return self.ReadU64(address) |
| 586 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 587 return self.ReadU32(address) |
544 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 588 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
545 return self.ReadU32(address) | 589 return self.ReadU32(address) |
546 | 590 |
547 def ReadBytes(self, address, size): | 591 def ReadBytes(self, address, size): |
548 location = self.FindLocation(address) | 592 location = self.FindLocation(address) |
549 return self.minidump[location:location + size] | 593 return self.minidump[location:location + size] |
550 | 594 |
551 def _ReadWord(self, location): | 595 def _ReadWord(self, location): |
552 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 596 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
553 return ctypes.c_uint64.from_buffer(self.minidump, location).value | 597 return ctypes.c_uint64.from_buffer(self.minidump, location).value |
| 598 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 599 return ctypes.c_uint32.from_buffer(self.minidump, location).value |
554 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 600 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
555 return ctypes.c_uint32.from_buffer(self.minidump, location).value | 601 return ctypes.c_uint32.from_buffer(self.minidump, location).value |
556 | 602 |
557 def IsProbableASCIIRegion(self, location, length): | 603 def IsProbableASCIIRegion(self, location, length): |
558 ascii_bytes = 0 | 604 ascii_bytes = 0 |
559 non_ascii_bytes = 0 | 605 non_ascii_bytes = 0 |
560 for loc in xrange(location, location + length): | 606 for loc in xrange(location, location + length): |
561 byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value | 607 byte = ctypes.c_uint8.from_buffer(self.minidump, loc).value |
562 if byte >= 0x7f: | 608 if byte >= 0x7f: |
563 non_ascii_bytes += 1 | 609 non_ascii_bytes += 1 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 if r.start <= address < r.start + r.size: | 686 if r.start <= address < r.start + r.size: |
641 return self.memory_list64.base_rva + offset + address - r.start | 687 return self.memory_list64.base_rva + offset + address - r.start |
642 offset += r.size | 688 offset += r.size |
643 if self.memory_list is not None: | 689 if self.memory_list is not None: |
644 for r in self.memory_list.ranges: | 690 for r in self.memory_list.ranges: |
645 if r.start <= address < r.start + r.memory.data_size: | 691 if r.start <= address < r.start + r.memory.data_size: |
646 return r.memory.rva + address - r.start | 692 return r.memory.rva + address - r.start |
647 return None | 693 return None |
648 | 694 |
649 def GetDisasmLines(self, address, size): | 695 def GetDisasmLines(self, address, size): |
| 696 def CountUndefinedInstructions(lines): |
| 697 pattern = "<UNDEFINED>" |
| 698 return sum([line.count(pattern) for (ignore, line) in lines]) |
| 699 |
650 location = self.FindLocation(address) | 700 location = self.FindLocation(address) |
651 if location is None: return [] | 701 if location is None: return [] |
652 arch = None | 702 arch = None |
| 703 possible_objdump_flags = [""] |
653 if self.arch == MD_CPU_ARCHITECTURE_X86: | 704 if self.arch == MD_CPU_ARCHITECTURE_X86: |
654 arch = "ia32" | 705 arch = "ia32" |
| 706 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 707 arch = "arm" |
| 708 possible_objdump_flags = ["", "--disassembler-options=force-thumb"] |
655 elif self.arch == MD_CPU_ARCHITECTURE_AMD64: | 709 elif self.arch == MD_CPU_ARCHITECTURE_AMD64: |
656 arch = "x64" | 710 arch = "x64" |
657 return disasm.GetDisasmLines(self.minidump_name, | 711 results = [ disasm.GetDisasmLines(self.minidump_name, |
658 location, | 712 location, |
659 size, | 713 size, |
660 arch, | 714 arch, |
661 False) | 715 False, |
| 716 objdump_flags) |
| 717 for objdump_flags in possible_objdump_flags ] |
| 718 return min(results, key=CountUndefinedInstructions) |
662 | 719 |
663 | 720 |
664 def Dispose(self): | 721 def Dispose(self): |
665 self.minidump.close() | 722 self.minidump.close() |
666 self.minidump_file.close() | 723 self.minidump_file.close() |
667 | 724 |
668 def ExceptionIP(self): | 725 def ExceptionIP(self): |
669 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 726 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
670 return self.exception_context.rip | 727 return self.exception_context.rip |
| 728 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 729 return self.exception_context.pc |
671 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 730 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
672 return self.exception_context.eip | 731 return self.exception_context.eip |
673 | 732 |
674 def ExceptionSP(self): | 733 def ExceptionSP(self): |
675 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 734 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
676 return self.exception_context.rsp | 735 return self.exception_context.rsp |
| 736 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 737 return self.exception_context.sp |
677 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 738 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
678 return self.exception_context.esp | 739 return self.exception_context.esp |
679 | 740 |
680 def FormatIntPtr(self, value): | 741 def FormatIntPtr(self, value): |
681 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 742 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
682 return "%016x" % value | 743 return "%016x" % value |
| 744 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 745 return "%08x" % value |
683 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 746 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
684 return "%08x" % value | 747 return "%08x" % value |
685 | 748 |
686 def PointerSize(self): | 749 def PointerSize(self): |
687 if self.arch == MD_CPU_ARCHITECTURE_AMD64: | 750 if self.arch == MD_CPU_ARCHITECTURE_AMD64: |
688 return 8 | 751 return 8 |
| 752 elif self.arch == MD_CPU_ARCHITECTURE_ARM: |
| 753 return 4 |
689 elif self.arch == MD_CPU_ARCHITECTURE_X86: | 754 elif self.arch == MD_CPU_ARCHITECTURE_X86: |
690 return 4 | 755 return 4 |
691 | 756 |
692 def Register(self, name): | 757 def Register(self, name): |
693 return self.exception_context.__getattribute__(name) | 758 return self.exception_context.__getattribute__(name) |
694 | 759 |
695 def ReadMinidumpString(self, rva): | 760 def ReadMinidumpString(self, rva): |
696 string = bytearray(MINIDUMP_STRING.Read(self.minidump, rva).buffer) | 761 string = bytearray(MINIDUMP_STRING.Read(self.minidump, rva).buffer) |
697 string = string.decode("utf16") | 762 string = string.decode("utf16") |
698 return string[0:len(string) - 1] | 763 return string[0:len(string) - 1] |
(...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1455 | 1520 |
1456 def PointerSize(self): | 1521 def PointerSize(self): |
1457 return self.reader.PointerSize() | 1522 return self.reader.PointerSize() |
1458 | 1523 |
1459 def ObjectAlignmentMask(self): | 1524 def ObjectAlignmentMask(self): |
1460 return self.PointerSize() - 1 | 1525 return self.PointerSize() - 1 |
1461 | 1526 |
1462 def MapAlignmentMask(self): | 1527 def MapAlignmentMask(self): |
1463 if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64: | 1528 if self.reader.arch == MD_CPU_ARCHITECTURE_AMD64: |
1464 return (1 << 4) - 1 | 1529 return (1 << 4) - 1 |
| 1530 elif self.reader.arch == MD_CPU_ARCHITECTURE_ARM: |
| 1531 return (1 << 4) - 1 |
1465 elif self.reader.arch == MD_CPU_ARCHITECTURE_X86: | 1532 elif self.reader.arch == MD_CPU_ARCHITECTURE_X86: |
1466 return (1 << 5) - 1 | 1533 return (1 << 5) - 1 |
1467 | 1534 |
1468 def PageAlignmentMask(self): | 1535 def PageAlignmentMask(self): |
1469 return (1 << 20) - 1 | 1536 return (1 << 20) - 1 |
1470 | 1537 |
1471 | 1538 |
1472 class KnownObject(HeapObject): | 1539 class KnownObject(HeapObject): |
1473 def __init__(self, heap, known_name): | 1540 def __init__(self, heap, known_name): |
1474 HeapObject.__init__(self, heap, None, None) | 1541 HeapObject.__init__(self, heap, None, None) |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 for line in lines: | 1806 for line in lines: |
1740 print FormatDisasmLine(start, self.heap, line) | 1807 print FormatDisasmLine(start, self.heap, line) |
1741 print | 1808 print |
1742 | 1809 |
1743 EIP_PROXIMITY = 64 | 1810 EIP_PROXIMITY = 64 |
1744 | 1811 |
1745 CONTEXT_FOR_ARCH = { | 1812 CONTEXT_FOR_ARCH = { |
1746 MD_CPU_ARCHITECTURE_AMD64: | 1813 MD_CPU_ARCHITECTURE_AMD64: |
1747 ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip', | 1814 ['rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp', 'rip', |
1748 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'], | 1815 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'], |
| 1816 MD_CPU_ARCHITECTURE_ARM: |
| 1817 ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', |
| 1818 'r10', 'r11', 'r12', 'sp', 'lr', 'pc'], |
1749 MD_CPU_ARCHITECTURE_X86: | 1819 MD_CPU_ARCHITECTURE_X86: |
1750 ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] | 1820 ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] |
1751 } | 1821 } |
1752 | 1822 |
1753 KNOWN_MODULES = {'chrome.exe', 'chrome.dll'} | 1823 KNOWN_MODULES = {'chrome.exe', 'chrome.dll'} |
1754 | 1824 |
1755 def GetModuleName(reader, module): | 1825 def GetModuleName(reader, module): |
1756 name = reader.ReadMinidumpString(module.module_name_rva) | 1826 name = reader.ReadMinidumpString(module.module_name_rva) |
1757 return str(os.path.basename(str(name).replace("\\", "/"))) | 1827 return str(os.path.basename(str(name).replace("\\", "/"))) |
1758 | 1828 |
1759 def AnalyzeMinidump(options, minidump_name): | 1829 def AnalyzeMinidump(options, minidump_name): |
1760 reader = MinidumpReader(options, minidump_name) | 1830 reader = MinidumpReader(options, minidump_name) |
1761 heap = None | 1831 heap = None |
1762 DebugPrint("========================================") | 1832 DebugPrint("========================================") |
1763 if reader.exception is None: | 1833 if reader.exception is None: |
1764 print "Minidump has no exception info" | 1834 print "Minidump has no exception info" |
1765 else: | 1835 else: |
1766 print "Exception info:" | 1836 print "Exception info:" |
1767 exception_thread = reader.thread_map[reader.exception.thread_id] | 1837 exception_thread = reader.thread_map[reader.exception.thread_id] |
1768 print " thread id: %d" % exception_thread.id | 1838 print " thread id: %d" % exception_thread.id |
1769 print " code: %08X" % reader.exception.exception.code | 1839 print " code: %08X" % reader.exception.exception.code |
1770 print " context:" | 1840 print " context:" |
1771 for r in CONTEXT_FOR_ARCH[reader.arch]: | 1841 for r in CONTEXT_FOR_ARCH[reader.arch]: |
1772 print " %s: %s" % (r, reader.FormatIntPtr(reader.Register(r))) | 1842 print " %s: %s" % (r, reader.FormatIntPtr(reader.Register(r))) |
1773 # TODO(vitalyr): decode eflags. | 1843 # TODO(vitalyr): decode eflags. |
1774 print " eflags: %s" % bin(reader.exception_context.eflags)[2:] | 1844 if reader.arch == MD_CPU_ARCHITECTURE_ARM: |
| 1845 print " cpsr: %s" % bin(reader.exception_context.cpsr)[2:] |
| 1846 else: |
| 1847 print " eflags: %s" % bin(reader.exception_context.eflags)[2:] |
| 1848 |
1775 print | 1849 print |
1776 print " modules:" | 1850 print " modules:" |
1777 for module in reader.module_list.modules: | 1851 for module in reader.module_list.modules: |
1778 name = GetModuleName(reader, module) | 1852 name = GetModuleName(reader, module) |
1779 if name in KNOWN_MODULES: | 1853 if name in KNOWN_MODULES: |
1780 print " %s at %08X" % (name, module.base_of_image) | 1854 print " %s at %08X" % (name, module.base_of_image) |
1781 reader.TryLoadSymbolsFor(name, module) | 1855 reader.TryLoadSymbolsFor(name, module) |
1782 print | 1856 print |
1783 | 1857 |
1784 stack_top = reader.ExceptionSP() | 1858 stack_top = reader.ExceptionSP() |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 | 1909 |
1836 | 1910 |
1837 if __name__ == "__main__": | 1911 if __name__ == "__main__": |
1838 parser = optparse.OptionParser(USAGE) | 1912 parser = optparse.OptionParser(USAGE) |
1839 parser.add_option("-s", "--shell", dest="shell", action="store_true", | 1913 parser.add_option("-s", "--shell", dest="shell", action="store_true", |
1840 help="start an interactive inspector shell") | 1914 help="start an interactive inspector shell") |
1841 parser.add_option("-f", "--full", dest="full", action="store_true", | 1915 parser.add_option("-f", "--full", dest="full", action="store_true", |
1842 help="dump all information contained in the minidump") | 1916 help="dump all information contained in the minidump") |
1843 parser.add_option("--symdir", dest="symdir", default=".", | 1917 parser.add_option("--symdir", dest="symdir", default=".", |
1844 help="directory containing *.pdb.sym file with symbols") | 1918 help="directory containing *.pdb.sym file with symbols") |
| 1919 parser.add_option("--objdump", |
| 1920 default="/usr/bin/objdump", |
| 1921 help="objdump tool to use [default: %default]") |
1845 options, args = parser.parse_args() | 1922 options, args = parser.parse_args() |
| 1923 if os.path.exists(options.objdump): |
| 1924 disasm.OBJDUMP_BIN = options.objdump |
| 1925 OBJDUMP_BIN = options.objdump |
| 1926 else: |
| 1927 print "Cannot find %s, falling back to default objdump" % options.objdump |
1846 if len(args) != 1: | 1928 if len(args) != 1: |
1847 parser.print_help() | 1929 parser.print_help() |
1848 sys.exit(1) | 1930 sys.exit(1) |
1849 AnalyzeMinidump(options, args[0]) | 1931 AnalyzeMinidump(options, args[0]) |
OLD | NEW |