Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(104)

Side by Side Diff: tools/valgrind/memcheck_analyze.py

Issue 175026: Remove the GDB-related code from memcheck_analyze.py to use it from tsan_analyze.py in the future. Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 11 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/valgrind/gdb_helper.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # memcheck_analyze.py 6 # memcheck_analyze.py
7 7
8 ''' Given a valgrind XML file, parses errors and uniques them.''' 8 ''' Given a valgrind XML file, parses errors and uniques them.'''
9 9
10 import gdb_helper
11
10 import logging 12 import logging
11 import optparse 13 import optparse
12 import os 14 import os
13 import re
14 import subprocess 15 import subprocess
15 import sys 16 import sys
16 import tempfile
17 import time 17 import time
18 from xml.dom.minidom import parse 18 from xml.dom.minidom import parse
19 from xml.parsers.expat import ExpatError 19 from xml.parsers.expat import ExpatError
20 20
21 # Global symbol table (yuck) 21 # Global symbol table (yuck)
22 TheAddressTable = None 22 TheAddressTable = None
23 23
24 GDB_LINE_RE = re.compile(r'Line ([0-9]*) of "([^"]*)".*')
25
26 def _GdbOutputToFileLine(output_line):
27 ''' Parse the gdb output line, return a pair (file, line num) '''
28 match = GDB_LINE_RE.match(output_line)
29 if match:
30 return match.groups()[1], match.groups()[0]
31 else:
32 return None
33
34 def ResolveAddressesWithinABinary(binary_name, load_address, address_list):
35 ''' For each address, return a pair (file, line num) '''
36 commands = tempfile.NamedTemporaryFile()
37 commands.write('add-symbol-file "%s" %s\n' % (binary_name, load_address))
38 for addr in address_list:
39 commands.write('info line *%s\n' % addr)
40 commands.write('quit\n')
41 commands.flush()
42 gdb_commandline = 'gdb -batch -x %s 2>/dev/null' % commands.name
43 gdb_pipe = os.popen(gdb_commandline)
44 result = gdb_pipe.readlines()
45
46 address_count = 0
47 ret = {}
48 for line in result:
49 if line.startswith('Line'):
50 ret[address_list[address_count]] = _GdbOutputToFileLine(line)
51 address_count += 1
52 if line.startswith('No line'):
53 ret[address_list[address_count]] = (None, None)
54 address_count += 1
55 gdb_pipe.close()
56 commands.close()
57 return ret
58
59 class _AddressTable(object):
60 ''' Object to do batched line number lookup. '''
61 def __init__(self):
62 self._load_addresses = {}
63 self._binaries = {}
64 self._all_resolved = False
65
66 def AddBinaryAt(self, binary, load_address):
67 ''' Register a new shared library or executable. '''
68 self._load_addresses[binary] = load_address
69
70 def Add(self, binary, address):
71 ''' Register a lookup request. '''
72 if binary == '':
73 logging.warn('adding address %s in empty binary?' % address)
74 if binary in self._binaries:
75 self._binaries[binary].append(address)
76 else:
77 self._binaries[binary] = [address]
78 self._all_resolved = False
79
80 def ResolveAll(self):
81 ''' Carry out all lookup requests. '''
82 self._translation = {}
83 for binary in self._binaries.keys():
84 if binary != '' and binary in self._load_addresses:
85 load_address = self._load_addresses[binary]
86 addr = ResolveAddressesWithinABinary(binary, load_address, self._binarie s[binary])
87 self._translation[binary] = addr
88 self._all_resolved = True
89
90 def GetFileLine(self, binary, addr):
91 ''' Get the (filename, linenum) result of a previously-registered lookup req uest. '''
92 if self._all_resolved:
93 if binary in self._translation:
94 if addr in self._translation[binary]:
95 return self._translation[binary][addr]
96 return (None, None)
97 24
98 # These are functions (using C++ mangled names) that we look for in stack 25 # These are functions (using C++ mangled names) that we look for in stack
99 # traces. We don't show stack frames while pretty printing when they are below 26 # traces. We don't show stack frames while pretty printing when they are below
100 # any of the following: 27 # any of the following:
101 _TOP_OF_STACK_POINTS = [ 28 _TOP_OF_STACK_POINTS = [
102 # Don't show our testing framework. 29 # Don't show our testing framework.
103 "testing::Test::Run()", 30 "testing::Test::Run()",
104 # Also don't show the internals of libc/pthread. 31 # Also don't show the internals of libc/pthread.
105 "start_thread" 32 "start_thread"
106 ] 33 ]
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 '''Reads in a set of files. 249 '''Reads in a set of files.
323 250
324 Args: 251 Args:
325 source_dir: Path to top of source tree for this build 252 source_dir: Path to top of source tree for this build
326 files: A list of filenames. 253 files: A list of filenames.
327 show_all_leaks: whether to show even less important leaks 254 show_all_leaks: whether to show even less important leaks
328 ''' 255 '''
329 256
330 if use_gdb: 257 if use_gdb:
331 global TheAddressTable 258 global TheAddressTable
332 TheAddressTable = _AddressTable() 259 TheAddressTable = gdb_helper.AddressTable()
333 self._errors = set() 260 self._errors = set()
334 badfiles = set() 261 badfiles = set()
335 start = time.time() 262 start = time.time()
336 self._parse_failed = False 263 self._parse_failed = False
337 for file in files: 264 for file in files:
338 # Wait up to three minutes for valgrind to finish writing all files, 265 # Wait up to three minutes for valgrind to finish writing all files,
339 # but after that, just skip incomplete files and warn. 266 # but after that, just skip incomplete files and warn.
340 f = open(file, "r+") 267 f = open(file, "r+")
341 found = False 268 found = False
342 firstrun = True 269 firstrun = True
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
428 parser.error("no filename specified") 355 parser.error("no filename specified")
429 filenames = args 356 filenames = args
430 357
431 analyzer = MemcheckAnalyze(options.source_dir, filenames, use_gdb=True) 358 analyzer = MemcheckAnalyze(options.source_dir, filenames, use_gdb=True)
432 retcode = analyzer.Report() 359 retcode = analyzer.Report()
433 360
434 sys.exit(retcode) 361 sys.exit(retcode)
435 362
436 if __name__ == "__main__": 363 if __name__ == "__main__":
437 _main() 364 _main()
OLDNEW
« no previous file with comments | « tools/valgrind/gdb_helper.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698