| Index: tools/grokdump.py
|
| diff --git a/tools/grokdump.py b/tools/grokdump.py
|
| index 9977289872bde66af4cef076dda312f27181e11b..8f1808c5b730d03e6c0ef1450a43ebf9da236839 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, 0)
|
| + 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()
|
| + 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()
|
|
|