summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authortimurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-23 11:25:01 +0000
committertimurrrr@chromium.org <timurrrr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-23 11:25:01 +0000
commitd1d4ad6c57150c75cea2ccc7022c6ab4cae50ceb (patch)
treed2aecabe7c70f130c86e3e515f0717378c0c7517 /tools
parentcfa0dc2ea1ef297b0e6498ba161cf6b0844dcda2 (diff)
downloadchromium_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')
-rw-r--r--tools/valgrind/gdb_helper.py87
-rwxr-xr-xtools/valgrind/memcheck_analyze.py79
2 files changed, 90 insertions, 76 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)
diff --git a/tools/valgrind/memcheck_analyze.py b/tools/valgrind/memcheck_analyze.py
index 82372c5..d0ac76b 100755
--- a/tools/valgrind/memcheck_analyze.py
+++ b/tools/valgrind/memcheck_analyze.py
@@ -7,13 +7,13 @@
''' Given a valgrind XML file, parses errors and uniques them.'''
+import gdb_helper
+
import logging
import optparse
import os
-import re
import subprocess
import sys
-import tempfile
import time
from xml.dom.minidom import parse
from xml.parsers.expat import ExpatError
@@ -21,79 +21,6 @@ from xml.parsers.expat import ExpatError
# Global symbol table (yuck)
TheAddressTable = None
-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)
# These are functions (using C++ mangled names) that we look for in stack
# traces. We don't show stack frames while pretty printing when they are below
@@ -394,7 +321,7 @@ class MemcheckAnalyze:
global TheAddressTable
if use_gdb:
- TheAddressTable = _AddressTable()
+ TheAddressTable = gdb_helper.AddressTable()
self._errors = set()
self._suppcounts = {}
badfiles = set()