Index: tools/grokdump.py |
diff --git a/tools/grokdump.py b/tools/grokdump.py |
index 1be5cb89e64527a9edb5671df254058a7c031b7e..c32081bc40b2f6eb0458ddfb6d6d7f0da618fd71 100755 |
--- a/tools/grokdump.py |
+++ b/tools/grokdump.py |
@@ -39,7 +39,7 @@ import re |
import struct |
import sys |
import types |
- |
+import datetime |
Michael Starzinger
2013/07/01 11:17:37
nit: Can we alpha-sort the imports?
|
USAGE="""usage: %prog [OPTIONS] [DUMP-FILE] |
@@ -442,13 +442,29 @@ MINIDUMP_THREAD_LIST = Descriptor([ |
("threads", lambda t: MINIDUMP_THREAD.ctype * t.thread_count) |
]) |
+MINIDUMP_VS_FIXEDFILEINFO = Descriptor([ |
+ ("dwSignature", ctypes.c_uint32), |
+ ("dwStrucVersion", ctypes.c_uint32), |
+ ("dwFileVersionMS", ctypes.c_uint32), |
+ ("dwFileVersionLS", ctypes.c_uint32), |
+ ("dwProductVersionMS", ctypes.c_uint32), |
+ ("dwProductVersionLS", ctypes.c_uint32), |
+ ("dwFileFlagsMask", ctypes.c_uint32), |
+ ("dwFileFlags", ctypes.c_uint32), |
+ ("dwFileOS", ctypes.c_uint32), |
+ ("dwFileType", ctypes.c_uint32), |
+ ("dwFileSubtype", ctypes.c_uint32), |
+ ("dwFileDateMS", ctypes.c_uint32), |
+ ("dwFileDateLS", ctypes.c_uint32) |
+]) |
+ |
MINIDUMP_RAW_MODULE = Descriptor([ |
("base_of_image", ctypes.c_uint64), |
("size_of_image", ctypes.c_uint32), |
("checksum", ctypes.c_uint32), |
("time_date_stamp", ctypes.c_uint32), |
("module_name_rva", ctypes.c_uint32), |
- ("version_info", ctypes.c_uint32 * 13), |
+ ("version_info", MINIDUMP_VS_FIXEDFILEINFO.ctype), |
("cv_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), |
("misc_record", MINIDUMP_LOCATION_DESCRIPTOR.ctype), |
("reserved0", ctypes.c_uint32 * 2), |
@@ -2011,6 +2027,21 @@ class InspectionShell(cmd.Cmd): |
print "Available memory regions:" |
self.reader.ForEachMemoryRegion(print_region) |
+ def do_lm(self, arg): |
+ """ |
+ List details for all loaded modules in the minidump. An argument can |
+ be passed to limit the output to only those modules that contain the |
+ argument as a substring (case insensitive match). |
+ """ |
+ for module in self.reader.module_list.modules: |
+ if arg: |
+ name = GetModuleName(self.reader, module).lower() |
+ if name.find(arg.lower()) >= 0: |
+ GetModuleDetails(self.reader, module) |
+ else: |
+ GetModuleDetails(self.reader, module) |
+ |
def do_s(self, word): |
""" |
Search for a given word in available memory regions. The given word |
@@ -2069,10 +2100,30 @@ CONTEXT_FOR_ARCH = { |
KNOWN_MODULES = {'chrome.exe', 'chrome.dll'} |
+def GetVersionString(ms, ls): |
+ return "%d.%d.%d.%d" % (ms >> 16, ms & 0xffff, ls >> 16, ls & 0xffff) |
+ |
+ |
def GetModuleName(reader, module): |
name = reader.ReadMinidumpString(module.module_name_rva) |
return str(os.path.basename(str(name).replace("\\", "/"))) |
+ |
+def GetModuleDetails(reader, module): |
Michael Starzinger
2013/07/01 11:17:37
nit: Can we rename this to PrintModuleDetails, I t
|
+ print "%s" % GetModuleName(reader, module) |
+ file_version = GetVersionString(module.version_info.dwFileVersionMS, |
+ module.version_info.dwFileVersionLS) |
+ product_version = GetVersionString(module.version_info.dwProductVersionMS, |
+ module.version_info.dwProductVersionLS) |
+ print " base: %s" % reader.FormatIntPtr(module.base_of_image) |
+ print " end: %s" % reader.FormatIntPtr(module.base_of_image + |
+ module.size_of_image) |
+ print " file version: %s" % file_version |
+ print " product version: %s" % product_version |
+ time_date_stamp = datetime.datetime.fromtimestamp(module.time_date_stamp) |
+ print " timestamp: %s" % time_date_stamp |
+ |
+ |
def AnalyzeMinidump(options, minidump_name): |
reader = MinidumpReader(options, minidump_name) |
heap = None |
@@ -2137,12 +2188,15 @@ def AnalyzeMinidump(options, minidump_name): |
if options.full: |
FullDump(reader, heap) |
+ if options.command: |
+ InspectionShell(reader, heap).onecmd(options.command) |
+ |
if options.shell: |
try: |
InspectionShell(reader, heap).cmdloop("type help to get help") |
except KeyboardInterrupt: |
print "Kthxbye." |
- else: |
+ elif not options.command: |
if reader.exception is not None: |
print "Annotated stack (from exception.esp to bottom):" |
for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): |
@@ -2163,6 +2217,8 @@ if __name__ == "__main__": |
parser = optparse.OptionParser(USAGE) |
parser.add_option("-s", "--shell", dest="shell", action="store_true", |
help="start an interactive inspector shell") |
+ parser.add_option("-c", "--command", dest="command", default="", |
+ help="run an interactive inspector shell command and exit") |
parser.add_option("-f", "--full", dest="full", action="store_true", |
help="dump all information contained in the minidump") |
parser.add_option("--symdir", dest="symdir", default=".", |