Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: tools/grokdump.py

Issue 18310003: Grokdump: new shell command, "lm" (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Whitespace issue Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 21 matching lines...) Expand all
32 import codecs 32 import codecs
33 import ctypes 33 import ctypes
34 import disasm 34 import disasm
35 import mmap 35 import mmap
36 import optparse 36 import optparse
37 import os 37 import os
38 import re 38 import re
39 import struct 39 import struct
40 import sys 40 import sys
41 import types 41 import types
42 42 import datetime
Michael Starzinger 2013/07/01 11:17:37 nit: Can we alpha-sort the imports?
43 43
44 USAGE="""usage: %prog [OPTIONS] [DUMP-FILE] 44 USAGE="""usage: %prog [OPTIONS] [DUMP-FILE]
45 45
46 Minidump analyzer. 46 Minidump analyzer.
47 47
48 Shows the processor state at the point of exception including the 48 Shows the processor state at the point of exception including the
49 stack of the active thread and the referenced objects in the V8 49 stack of the active thread and the referenced objects in the V8
50 heap. Code objects are disassembled and the addresses linked from the 50 heap. Code objects are disassembled and the addresses linked from the
51 stack (e.g. pushed return addresses) are marked with "=>". 51 stack (e.g. pushed return addresses) are marked with "=>".
52 52
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 ("ted", ctypes.c_uint64), 435 ("ted", ctypes.c_uint64),
436 ("stack", MINIDUMP_MEMORY_DESCRIPTOR.ctype), 436 ("stack", MINIDUMP_MEMORY_DESCRIPTOR.ctype),
437 ("context", MINIDUMP_LOCATION_DESCRIPTOR.ctype) 437 ("context", MINIDUMP_LOCATION_DESCRIPTOR.ctype)
438 ]) 438 ])
439 439
440 MINIDUMP_THREAD_LIST = Descriptor([ 440 MINIDUMP_THREAD_LIST = Descriptor([
441 ("thread_count", ctypes.c_uint32), 441 ("thread_count", ctypes.c_uint32),
442 ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) 442 ("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count)
443 ]) 443 ])
444 444
445 MINIDUMP_VS_FIXEDFILEINFO = Descriptor([
446 ("dwSignature", ctypes.c_uint32),
447 ("dwStrucVersion", ctypes.c_uint32),
448 ("dwFileVersionMS", ctypes.c_uint32),
449 ("dwFileVersionLS", ctypes.c_uint32),
450 ("dwProductVersionMS", ctypes.c_uint32),
451 ("dwProductVersionLS", ctypes.c_uint32),
452 ("dwFileFlagsMask", ctypes.c_uint32),
453 ("dwFileFlags", ctypes.c_uint32),
454 ("dwFileOS", ctypes.c_uint32),
455 ("dwFileType", ctypes.c_uint32),
456 ("dwFileSubtype", ctypes.c_uint32),
457 ("dwFileDateMS", ctypes.c_uint32),
458 ("dwFileDateLS", ctypes.c_uint32)
459 ])
460
445 MINIDUMP_RAW_MODULE = Descriptor([ 461 MINIDUMP_RAW_MODULE = Descriptor([
446 ("base_of_image", ctypes.c_uint64), 462 ("base_of_image", ctypes.c_uint64),
447 ("size_of_image", ctypes.c_uint32), 463 ("size_of_image", ctypes.c_uint32),
448 ("checksum", ctypes.c_uint32), 464 ("checksum", ctypes.c_uint32),
449 ("time_date_stamp", ctypes.c_uint32), 465 ("time_date_stamp", ctypes.c_uint32),
450 ("module_name_rva", ctypes.c_uint32), 466 ("module_name_rva", ctypes.c_uint32),
451 ("version_info", ctypes.c_uint32 * 13), 467 ("version_info", MINIDUMP_VS_FIXEDFILEINFO.ctype),
452 ("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), 468 ("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype),
453 ("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), 469 ("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype),
454 ("reserved0", ctypes.c_uint32 * 2), 470 ("reserved0", ctypes.c_uint32 * 2),
455 ("reserved1", ctypes.c_uint32 * 2) 471 ("reserved1", ctypes.c_uint32 * 2)
456 ]) 472 ])
457 473
458 MINIDUMP_MODULE_LIST = Descriptor([ 474 MINIDUMP_MODULE_LIST = Descriptor([
459 ("number_of_modules", ctypes.c_uint32), 475 ("number_of_modules", ctypes.c_uint32),
460 ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules) 476 ("modules", lambda t: MINIDUMP_RAW_MODULE.ctype * t.number_of_modules)
461 ]) 477 ])
(...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after
2004 """ 2020 """
2005 List all available memory regions. 2021 List all available memory regions.
2006 """ 2022 """
2007 def print_region(reader, start, size, location): 2023 def print_region(reader, start, size, location):
2008 print " %s - %s (%d bytes)" % (reader.FormatIntPtr(start), 2024 print " %s - %s (%d bytes)" % (reader.FormatIntPtr(start),
2009 reader.FormatIntPtr(start + size), 2025 reader.FormatIntPtr(start + size),
2010 size) 2026 size)
2011 print "Available memory regions:" 2027 print "Available memory regions:"
2012 self.reader.ForEachMemoryRegion(print_region) 2028 self.reader.ForEachMemoryRegion(print_region)
2013 2029
2030 def do_lm(self, arg):
2031 """
2032 List details for all loaded modules in the minidump. An argument can
2033 be passed to limit the output to only those modules that contain the
2034 argument as a substring (case insensitive match).
2035 """
2036 for module in self.reader.module_list.modules:
2037 if arg:
2038 name = GetModuleName(self.reader, module).lower()
2039 if name.find(arg.lower()) >= 0:
2040 GetModuleDetails(self.reader, module)
2041 else:
2042 GetModuleDetails(self.reader, module)
2043 print
2044
2014 def do_s(self, word): 2045 def do_s(self, word):
2015 """ 2046 """
2016 Search for a given word in available memory regions. The given word 2047 Search for a given word in available memory regions. The given word
2017 is expanded to full pointer size and searched at aligned as well as 2048 is expanded to full pointer size and searched at aligned as well as
2018 un-aligned memory locations. Use 'sa' to search aligned locations 2049 un-aligned memory locations. Use 'sa' to search aligned locations
2019 only. 2050 only.
2020 """ 2051 """
2021 try: 2052 try:
2022 word = int(word, 0) 2053 word = int(word, 0)
2023 except ValueError: 2054 except ValueError:
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'], 2093 'r8', 'r9', 'r10', 'r11', 'r12', 'r13', 'r14', 'r15'],
2063 MD_CPU_ARCHITECTURE_ARM: 2094 MD_CPU_ARCHITECTURE_ARM:
2064 ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9', 2095 ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9',
2065 'r10', 'r11', 'r12', 'sp', 'lr', 'pc'], 2096 'r10', 'r11', 'r12', 'sp', 'lr', 'pc'],
2066 MD_CPU_ARCHITECTURE_X86: 2097 MD_CPU_ARCHITECTURE_X86:
2067 ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] 2098 ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip']
2068 } 2099 }
2069 2100
2070 KNOWN_MODULES = {'chrome.exe', 'chrome.dll'} 2101 KNOWN_MODULES = {'chrome.exe', 'chrome.dll'}
2071 2102
2103 def GetVersionString(ms, ls):
2104 return "%d.%d.%d.%d" % (ms >> 16, ms & 0xffff, ls >> 16, ls & 0xffff)
2105
2106
2072 def GetModuleName(reader, module): 2107 def GetModuleName(reader, module):
2073 name = reader.ReadMinidumpString(module.module_name_rva) 2108 name = reader.ReadMinidumpString(module.module_name_rva)
2074 return str(os.path.basename(str(name).replace("\\", "/"))) 2109 return str(os.path.basename(str(name).replace("\\", "/")))
2075 2110
2111
2112 def GetModuleDetails(reader, module):
Michael Starzinger 2013/07/01 11:17:37 nit: Can we rename this to PrintModuleDetails, I t
2113 print "%s" % GetModuleName(reader, module)
2114 file_version = GetVersionString(module.version_info.dwFileVersionMS,
2115 module.version_info.dwFileVersionLS)
2116 product_version = GetVersionString(module.version_info.dwProductVersionMS,
2117 module.version_info.dwProductVersionLS)
2118 print " base: %s" % reader.FormatIntPtr(module.base_of_image)
2119 print " end: %s" % reader.FormatIntPtr(module.base_of_image +
2120 module.size_of_image)
2121 print " file version: %s" % file_version
2122 print " product version: %s" % product_version
2123 time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp)
2124 print " timestamp: %s" % time_date_stamp
2125
2126
2076 def AnalyzeMinidump(options, minidump_name): 2127 def AnalyzeMinidump(options, minidump_name):
2077 reader = MinidumpReader(options, minidump_name) 2128 reader = MinidumpReader(options, minidump_name)
2078 heap = None 2129 heap = None
2079 DebugPrint("========================================") 2130 DebugPrint("========================================")
2080 if reader.exception is None: 2131 if reader.exception is None:
2081 print "Minidump has no exception info" 2132 print "Minidump has no exception info"
2082 else: 2133 else:
2083 print "Exception info:" 2134 print "Exception info:"
2084 exception_thread = reader.thread_map[reader.exception.thread_id] 2135 exception_thread = reader.thread_map[reader.exception.thread_id]
2085 print " thread id: %d" % exception_thread.id 2136 print " thread id: %d" % exception_thread.id
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2130 for line in lines: 2181 for line in lines:
2131 print FormatDisasmLine(disasm_start, heap, line) 2182 print FormatDisasmLine(disasm_start, heap, line)
2132 print 2183 print
2133 2184
2134 if heap is None: 2185 if heap is None:
2135 heap = V8Heap(reader, None) 2186 heap = V8Heap(reader, None)
2136 2187
2137 if options.full: 2188 if options.full:
2138 FullDump(reader, heap) 2189 FullDump(reader, heap)
2139 2190
2191 if options.command:
2192 InspectionShell(reader, heap).onecmd(options.command)
2193
2140 if options.shell: 2194 if options.shell:
2141 try: 2195 try:
2142 InspectionShell(reader, heap).cmdloop("type help to get help") 2196 InspectionShell(reader, heap).cmdloop("type help to get help")
2143 except KeyboardInterrupt: 2197 except KeyboardInterrupt:
2144 print "Kthxbye." 2198 print "Kthxbye."
2145 else: 2199 elif not options.command:
2146 if reader.exception is not None: 2200 if reader.exception is not None:
2147 print "Annotated stack (from exception.esp to bottom):" 2201 print "Annotated stack (from exception.esp to bottom):"
2148 for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): 2202 for slot in xrange(stack_top, stack_bottom, reader.PointerSize()):
2149 maybe_address = reader.ReadUIntPtr(slot) 2203 maybe_address = reader.ReadUIntPtr(slot)
2150 heap_object = heap.FindObject(maybe_address) 2204 heap_object = heap.FindObject(maybe_address)
2151 maybe_symbol = reader.FindSymbol(maybe_address) 2205 maybe_symbol = reader.FindSymbol(maybe_address)
2152 print "%s: %s %s" % (reader.FormatIntPtr(slot), 2206 print "%s: %s %s" % (reader.FormatIntPtr(slot),
2153 reader.FormatIntPtr(maybe_address), 2207 reader.FormatIntPtr(maybe_address),
2154 maybe_symbol or "") 2208 maybe_symbol or "")
2155 if heap_object: 2209 if heap_object:
2156 heap_object.Print(Printer()) 2210 heap_object.Print(Printer())
2157 print 2211 print
2158 2212
2159 reader.Dispose() 2213 reader.Dispose()
2160 2214
2161 2215
2162 if __name__ == "__main__": 2216 if __name__ == "__main__":
2163 parser = optparse.OptionParser(USAGE) 2217 parser = optparse.OptionParser(USAGE)
2164 parser.add_option("-s", "--shell", dest="shell", action="store_true", 2218 parser.add_option("-s", "--shell", dest="shell", action="store_true",
2165 help="start an interactive inspector shell") 2219 help="start an interactive inspector shell")
2220 parser.add_option("-c", "--command", dest="command", default="",
2221 help="run an interactive inspector shell command and exit")
2166 parser.add_option("-f", "--full", dest="full", action="store_true", 2222 parser.add_option("-f", "--full", dest="full", action="store_true",
2167 help="dump all information contained in the minidump") 2223 help="dump all information contained in the minidump")
2168 parser.add_option("--symdir", dest="symdir", default=".", 2224 parser.add_option("--symdir", dest="symdir", default=".",
2169 help="directory containing *.pdb.sym file with symbols") 2225 help="directory containing *.pdb.sym file with symbols")
2170 parser.add_option("--objdump", 2226 parser.add_option("--objdump",
2171 default="/usr/bin/objdump", 2227 default="/usr/bin/objdump",
2172 help="objdump tool to use [default: %default]") 2228 help="objdump tool to use [default: %default]")
2173 options, args = parser.parse_args() 2229 options, args = parser.parse_args()
2174 if os.path.exists(options.objdump): 2230 if os.path.exists(options.objdump):
2175 disasm.OBJDUMP_BIN = options.objdump 2231 disasm.OBJDUMP_BIN = options.objdump
2176 OBJDUMP_BIN = options.objdump 2232 OBJDUMP_BIN = options.objdump
2177 else: 2233 else:
2178 print "Cannot find %s, falling back to default objdump" % options.objdump 2234 print "Cannot find %s, falling back to default objdump" % options.objdump
2179 if len(args) != 1: 2235 if len(args) != 1:
2180 parser.print_help() 2236 parser.print_help()
2181 sys.exit(1) 2237 sys.exit(1)
2182 AnalyzeMinidump(options, args[0]) 2238 AnalyzeMinidump(options, args[0])
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698