| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2011 the V8 project authors. All rights reserved. | 3 # Copyright 2011 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 class Raw(ctypes.Structure): | 101 class Raw(ctypes.Structure): |
| 102 _fields_ = fields | 102 _fields_ = fields |
| 103 _pack_ = 1 | 103 _pack_ = 1 |
| 104 | 104 |
| 105 def __str__(self): | 105 def __str__(self): |
| 106 return "{" + ", ".join("%s: %s" % (field, self.__getattribute__(field)) | 106 return "{" + ", ".join("%s: %s" % (field, self.__getattribute__(field)) |
| 107 for field, _ in Raw._fields_) + "}" | 107 for field, _ in Raw._fields_) + "}" |
| 108 return Raw | 108 return Raw |
| 109 | 109 |
| 110 | 110 |
| 111 def do_dump(reader, heap): |
| 112 """Dump all available memory regions.""" |
| 113 def dump_region(reader, start, size, location): |
| 114 print "%s - %s" % (reader.FormatIntPtr(start), |
| 115 reader.FormatIntPtr(start + size)) |
| 116 for slot in xrange(start, |
| 117 start + size, |
| 118 reader.PointerSize()): |
| 119 maybe_address = reader.ReadUIntPtr(slot) |
| 120 heap_object = heap.FindObject(maybe_address) |
| 121 print "%s: %s" % (reader.FormatIntPtr(slot), |
| 122 reader.FormatIntPtr(maybe_address)) |
| 123 if heap_object: |
| 124 heap_object.Print(Printer()) |
| 125 print |
| 126 |
| 127 reader.ForEachMemoryRegion(dump_region) |
| 128 |
| 111 # Set of structures and constants that describe the layout of minidump | 129 # Set of structures and constants that describe the layout of minidump |
| 112 # files. Based on MSDN and Google Breakpad. | 130 # files. Based on MSDN and Google Breakpad. |
| 113 | 131 |
| 114 MINIDUMP_HEADER = Descriptor([ | 132 MINIDUMP_HEADER = Descriptor([ |
| 115 ("signature", ctypes.c_uint32), | 133 ("signature", ctypes.c_uint32), |
| 116 ("version", ctypes.c_uint32), | 134 ("version", ctypes.c_uint32), |
| 117 ("stream_count", ctypes.c_uint32), | 135 ("stream_count", ctypes.c_uint32), |
| 118 ("stream_directories_rva", ctypes.c_uint32), | 136 ("stream_directories_rva", ctypes.c_uint32), |
| 119 ("checksum", ctypes.c_uint32), | 137 ("checksum", ctypes.c_uint32), |
| 120 ("time_date_stampt", ctypes.c_uint32), | 138 ("time_date_stampt", ctypes.c_uint32), |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 767 | 785 |
| 768 def RightOffset(self): | 786 def RightOffset(self): |
| 769 return self.heap.PointerSize() * 4 | 787 return self.heap.PointerSize() * 4 |
| 770 | 788 |
| 771 def __init__(self, heap, map, address): | 789 def __init__(self, heap, map, address): |
| 772 String.__init__(self, heap, map, address) | 790 String.__init__(self, heap, map, address) |
| 773 self.left = self.ObjectField(self.LeftOffset()) | 791 self.left = self.ObjectField(self.LeftOffset()) |
| 774 self.right = self.ObjectField(self.RightOffset()) | 792 self.right = self.ObjectField(self.RightOffset()) |
| 775 | 793 |
| 776 def GetChars(self): | 794 def GetChars(self): |
| 777 return self.left.GetChars() + self.right.GetChars() | 795 try: |
| 796 return self.left.GetChars() + self.right.GetChars() |
| 797 except: |
| 798 return "***CAUGHT EXCEPTION IN GROKDUMP***" |
| 778 | 799 |
| 779 | 800 |
| 780 class Oddball(HeapObject): | 801 class Oddball(HeapObject): |
| 781 def ToStringOffset(self): | 802 def ToStringOffset(self): |
| 782 return self.heap.PointerSize() | 803 return self.heap.PointerSize() |
| 783 | 804 |
| 784 def __init__(self, heap, map, address): | 805 def __init__(self, heap, map, address): |
| 785 HeapObject.__init__(self, heap, map, address) | 806 HeapObject.__init__(self, heap, map, address) |
| 786 self.to_string = self.ObjectField(self.ToStringOffset()) | 807 self.to_string = self.ObjectField(self.ToStringOffset()) |
| 787 | 808 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1103 stack_map[maybe_address] = slot | 1124 stack_map[maybe_address] = slot |
| 1104 heap = V8Heap(reader, stack_map) | 1125 heap = V8Heap(reader, stack_map) |
| 1105 | 1126 |
| 1106 print "Disassembly around exception.eip:" | 1127 print "Disassembly around exception.eip:" |
| 1107 start = reader.ExceptionIP() - EIP_PROXIMITY | 1128 start = reader.ExceptionIP() - EIP_PROXIMITY |
| 1108 lines = reader.GetDisasmLines(start, 2 * EIP_PROXIMITY) | 1129 lines = reader.GetDisasmLines(start, 2 * EIP_PROXIMITY) |
| 1109 for line in lines: | 1130 for line in lines: |
| 1110 print FormatDisasmLine(start, heap, line) | 1131 print FormatDisasmLine(start, heap, line) |
| 1111 print | 1132 print |
| 1112 | 1133 |
| 1134 if options.full: |
| 1135 do_dump(reader, heap) |
| 1136 |
| 1113 if options.shell: | 1137 if options.shell: |
| 1114 InspectionShell(reader, heap).cmdloop("type help to get help") | 1138 InspectionShell(reader, heap).cmdloop("type help to get help") |
| 1115 else: | 1139 else: |
| 1116 print "Annotated stack (from exception.esp to bottom):" | 1140 print "Annotated stack (from exception.esp to bottom):" |
| 1117 for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): | 1141 for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): |
| 1118 maybe_address = reader.ReadUIntPtr(slot) | 1142 maybe_address = reader.ReadUIntPtr(slot) |
| 1119 heap_object = heap.FindObject(maybe_address) | 1143 heap_object = heap.FindObject(maybe_address) |
| 1120 print "%s: %s" % (reader.FormatIntPtr(slot), | 1144 print "%s: %s" % (reader.FormatIntPtr(slot), |
| 1121 reader.FormatIntPtr(maybe_address)) | 1145 reader.FormatIntPtr(maybe_address)) |
| 1122 if heap_object: | 1146 if heap_object: |
| 1123 heap_object.Print(Printer()) | 1147 heap_object.Print(Printer()) |
| 1124 print | 1148 print |
| 1125 | 1149 |
| 1126 reader.Dispose() | 1150 reader.Dispose() |
| 1127 | 1151 |
| 1128 | 1152 |
| 1129 if __name__ == "__main__": | 1153 if __name__ == "__main__": |
| 1130 parser = optparse.OptionParser(USAGE) | 1154 parser = optparse.OptionParser(USAGE) |
| 1131 parser.add_option("-s", "--shell", dest="shell", action="store_true") | 1155 parser.add_option("-s", "--shell", dest="shell", action="store_true") |
| 1156 parser.add_option("-f", "--full", dest="full", action="store_true") |
| 1132 options, args = parser.parse_args() | 1157 options, args = parser.parse_args() |
| 1133 if len(args) != 1: | 1158 if len(args) != 1: |
| 1134 parser.print_help() | 1159 parser.print_help() |
| 1135 sys.exit(1) | 1160 sys.exit(1) |
| 1136 AnalyzeMinidump(options, args[0]) | 1161 AnalyzeMinidump(options, args[0]) |
| OLD | NEW |