From 818aba70b203f16e659a1e8ade72eccaa7addb08 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Thu, 10 May 2012 12:44:15 +0000 Subject: [PATCH] Extend grokdump with basic interactive shell capabilities. Supported commands: - dd: to print memory region - s: to search for a word in available memory regions - list: to list available memory regions R=mstarzinger@chromium.org Review URL: https://chromiumcodereview.appspot.com/10378087 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11537 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- tools/grokdump.py | 87 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/tools/grokdump.py b/tools/grokdump.py index 9977289..f5df489 100755 --- a/tools/grokdump.py +++ b/tools/grokdump.py @@ -27,6 +27,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import cmd import ctypes import mmap import optparse @@ -36,6 +37,7 @@ import sys import types import codecs import re +import struct USAGE="""usage: %prog [OPTION]... @@ -444,6 +446,33 @@ class MinidumpReader(object): location = self.FindLocation(address) return self.minidump[location:location + size] + def _ReadWord(self, location): + if self.arch == MD_CPU_ARCHITECTURE_AMD64: + return ctypes.c_uint64.from_buffer(self.minidump, location).value + elif self.arch == MD_CPU_ARCHITECTURE_X86: + return ctypes.c_uint32.from_buffer(self.minidump, location).value + + def ForEachMemoryRegion(self, cb): + if self.memory_list64 is not None: + for r in self.memory_list64.ranges: + location = self.memory_list64.base_rva + offset + cb(self, r.start, r.size, location) + offset += r.size + + if self.memory_list is not None: + for r in self.memory_list.ranges: + cb(self, r.start, r.memory.data_size, r.memory.rva) + + def FindWord(self, word): + def search_inside_region(reader, start, size, location): + for loc in xrange(location, location + size): + if reader._ReadWord(loc) == word: + slot = start + (loc - location) + print "%s: %s" % (reader.FormatIntPtr(slot), + reader.FormatIntPtr(word)) + + self.ForEachMemoryRegion(search_inside_region) + def FindLocation(self, address): offset = 0 if self.memory_list64 is not None: @@ -1011,6 +1040,42 @@ CONTEXT_FOR_ARCH = { ['eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'eip'] } +class InspectionShell(cmd.Cmd): + def __init__(self, reader, heap): + cmd.Cmd.__init__(self) + self.reader = reader + self.heap = heap + self.prompt = "(grok) " + + def do_dd(self, address): + "Interpret memory at the given address (if available)"\ + " as a sequence of words." + start = int(address, 16) + for slot in xrange(start, + start + self.reader.PointerSize() * 10, + self.reader.PointerSize()): + maybe_address = self.reader.ReadUIntPtr(slot) + heap_object = self.heap.FindObject(maybe_address) + print "%s: %s" % (self.reader.FormatIntPtr(slot), + self.reader.FormatIntPtr(maybe_address)) + if heap_object: + heap_object.Print(Printer()) + print + + def do_s(self, word): + "Search for a given word in available memory regions" + word = int(word, 0) + print "searching for word", word + self.reader.FindWord(word) + + def do_list(self, smth): + """List all available memory regions.""" + def print_region(reader, start, size, location): + print "%s - %s" % (reader.FormatIntPtr(start), + reader.FormatIntPtr(start + size)) + + self.reader.ForEachMemoryRegion(print_region) + def AnalyzeMinidump(options, minidump_name): reader = MinidumpReader(options, minidump_name) DebugPrint("========================================") @@ -1045,21 +1110,25 @@ def AnalyzeMinidump(options, minidump_name): print FormatDisasmLine(start, heap, line) print - print "Annotated stack (from exception.esp to bottom):" - for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): - maybe_address = reader.ReadUIntPtr(slot) - heap_object = heap.FindObject(maybe_address) - print "%s: %s" % (reader.FormatIntPtr(slot), - reader.FormatIntPtr(maybe_address)) - if heap_object: - heap_object.Print(Printer()) - print + if options.shell: + InspectionShell(reader, heap).cmdloop("type help to get help") + else: + print "Annotated stack (from exception.esp to bottom):" + for slot in xrange(stack_top, stack_bottom, reader.PointerSize()): + maybe_address = reader.ReadUIntPtr(slot) + heap_object = heap.FindObject(maybe_address) + print "%s: %s" % (reader.FormatIntPtr(slot), + reader.FormatIntPtr(maybe_address)) + if heap_object: + heap_object.Print(Printer()) + print reader.Dispose() if __name__ == "__main__": parser = optparse.OptionParser(USAGE) + parser.add_option("-s", "--shell", dest="shell", action="store_true") options, args = parser.parse_args() if len(args) != 1: parser.print_help() -- 2.7.4