diff options
author | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 11:25:01 +0000 |
---|---|---|
committer | timurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 11:25:01 +0000 |
commit | d1d4ad6c57150c75cea2ccc7022c6ab4cae50ceb (patch) | |
tree | d2aecabe7c70f130c86e3e515f0717378c0c7517 /tools/valgrind/gdb_helper.py | |
parent | cfa0dc2ea1ef297b0e6498ba161cf6b0844dcda2 (diff) | |
download | chromium_src-d1d4ad6c57150c75cea2ccc7022c6ab4cae50ceb.zip chromium_src-d1d4ad6c57150c75cea2ccc7022c6ab4cae50ceb.tar.gz chromium_src-d1d4ad6c57150c75cea2ccc7022c6ab4cae50ceb.tar.bz2 |
GDB wrapper refactoring for memcheck_analyze.py
(This changelist is prepared by Alexander Potapenko, cc'ed)
This is a small refactoring that moves the GDB querying logic into a
separate module to allow us using it from tsan_analyze as well (we need it finally).
The diff is almost equal to http://codereview.chromium.org/175026,
I've only swapped two lines to make it applicable to the current trunk version.
Review URL: http://codereview.chromium.org/211023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26911 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/valgrind/gdb_helper.py')
-rw-r--r-- | tools/valgrind/gdb_helper.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/tools/valgrind/gdb_helper.py b/tools/valgrind/gdb_helper.py new file mode 100644 index 0000000..9b57c84 --- /dev/null +++ b/tools/valgrind/gdb_helper.py @@ -0,0 +1,87 @@ +#!/usr/bin/python +# Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# gdb_helper.py + +''' A bunch of helper functions for querying gdb.''' + +import logging +import os +import re +import tempfile + +GDB_LINE_RE = re.compile(r'Line ([0-9]*) of "([^"]*)".*') + +def _GdbOutputToFileLine(output_line): + ''' Parse the gdb output line, return a pair (file, line num) ''' + match = GDB_LINE_RE.match(output_line) + if match: + return match.groups()[1], match.groups()[0] + else: + return None + +def ResolveAddressesWithinABinary(binary_name, load_address, address_list): + ''' For each address, return a pair (file, line num) ''' + commands = tempfile.NamedTemporaryFile() + commands.write('add-symbol-file "%s" %s\n' % (binary_name, load_address)) + for addr in address_list: + commands.write('info line *%s\n' % addr) + commands.write('quit\n') + commands.flush() + gdb_commandline = 'gdb -batch -x %s 2>/dev/null' % commands.name + gdb_pipe = os.popen(gdb_commandline) + result = gdb_pipe.readlines() + + address_count = 0 + ret = {} + for line in result: + if line.startswith('Line'): + ret[address_list[address_count]] = _GdbOutputToFileLine(line) + address_count += 1 + if line.startswith('No line'): + ret[address_list[address_count]] = (None, None) + address_count += 1 + gdb_pipe.close() + commands.close() + return ret + +class AddressTable(object): + ''' Object to do batched line number lookup. ''' + def __init__(self): + self._load_addresses = {} + self._binaries = {} + self._all_resolved = False + + def AddBinaryAt(self, binary, load_address): + ''' Register a new shared library or executable. ''' + self._load_addresses[binary] = load_address + + def Add(self, binary, address): + ''' Register a lookup request. ''' + if binary == '': + logging.warn('adding address %s in empty binary?' % address) + if binary in self._binaries: + self._binaries[binary].append(address) + else: + self._binaries[binary] = [address] + self._all_resolved = False + + def ResolveAll(self): + ''' Carry out all lookup requests. ''' + self._translation = {} + for binary in self._binaries.keys(): + if binary != '' and binary in self._load_addresses: + load_address = self._load_addresses[binary] + addr = ResolveAddressesWithinABinary(binary, load_address, self._binaries[binary]) + self._translation[binary] = addr + self._all_resolved = True + + def GetFileLine(self, binary, addr): + ''' Get the (filename, linenum) result of a previously-registered lookup request. ''' + if self._all_resolved: + if binary in self._translation: + if addr in self._translation[binary]: + return self._translation[binary][addr] + return (None, None) |