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

Side by Side Diff: tools/find_runtime_symbols/find_runtime_symbols.py

Issue 13514003: Breakdown memory usage by source file names in dmprof. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 8 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 """Find symbols in a binary corresponding to given runtime virtual addresses.
5 6
7 Note that source file names are treated as symbols in this script while they
8 are actually not.
9 """
10
11 import collections
6 import json 12 import json
7 import logging 13 import logging
8 import os 14 import os
9 import sys 15 import sys
10 16
11 from static_symbols import StaticSymbolsInFile 17 from static_symbols import StaticSymbolsInFile
12 from proc_maps import ProcMaps 18 from proc_maps import ProcMaps
13 19
14 20
21 FUNCTION_SYMBOLS = 0
22 SOURCEFILE_SYMBOLS = 1
23 TYPEINFO_SYMBOLS = 2
24
15 _MAPS_FILENAME = 'maps' 25 _MAPS_FILENAME = 'maps'
16 _FILES_FILENAME = 'files.json' 26 _FILES_FILENAME = 'files.json'
17 27
18 28
19 class _ListOutput(object):
20 def __init__(self, result):
21 self.result = result
22
23 def output(self, address, symbol): # pylint: disable=W0613
24 self.result.append(symbol)
25
26
27 class _DictOutput(object):
28 def __init__(self, result):
29 self.result = result
30
31 def output(self, address, symbol):
32 self.result[address] = symbol
33
34
35 class _FileOutput(object):
36 def __init__(self, result, with_address):
37 self.result = result
38 self.with_address = with_address
39
40 def output(self, address, symbol):
41 if self.with_address:
42 self.result.write('%016x %s\n' % (address, symbol))
43 else:
44 self.result.write('%s\n' % symbol)
45
46
47 class RuntimeSymbolsInProcess(object): 29 class RuntimeSymbolsInProcess(object):
48 def __init__(self): 30 def __init__(self):
49 self._maps = None 31 self._maps = None
50 self._static_symbols_in_filse = {} 32 self._static_symbols_in_filse = {}
51 33
52 def find_procedure(self, runtime_address): 34 def find_procedure(self, runtime_address):
53 for vma in self._maps.iter(ProcMaps.executable): 35 for vma in self._maps.iter(ProcMaps.executable):
54 if vma.begin <= runtime_address < vma.end: 36 if vma.begin <= runtime_address < vma.end:
55 static_symbols = self._static_symbols_in_filse.get(vma.name) 37 static_symbols = self._static_symbols_in_filse.get(vma.name)
56 if static_symbols: 38 if static_symbols:
57 return static_symbols.find_procedure_by_runtime_address( 39 return static_symbols.find_procedure_by_runtime_address(
58 runtime_address, vma) 40 runtime_address, vma)
59 else: 41 else:
60 return None 42 return None
61 return None 43 return None
62 44
45 def find_sourcefile(self, runtime_address):
46 for vma in self._maps.iter(ProcMaps.executable):
47 if vma.begin <= runtime_address < vma.end:
48 static_symbols = self._static_symbols_in_filse.get(vma.name)
49 if static_symbols:
50 return static_symbols.find_sourcefile_by_runtime_address(
51 runtime_address, vma)
52 else:
53 return None
54 return None
55
63 def find_typeinfo(self, runtime_address): 56 def find_typeinfo(self, runtime_address):
64 for vma in self._maps.iter(ProcMaps.constants): 57 for vma in self._maps.iter(ProcMaps.constants):
65 if vma.begin <= runtime_address < vma.end: 58 if vma.begin <= runtime_address < vma.end:
66 static_symbols = self._static_symbols_in_filse.get(vma.name) 59 static_symbols = self._static_symbols_in_filse.get(vma.name)
67 if static_symbols: 60 if static_symbols:
68 return static_symbols.find_typeinfo_by_runtime_address( 61 return static_symbols.find_typeinfo_by_runtime_address(
69 runtime_address, vma) 62 runtime_address, vma)
70 else: 63 else:
71 return None 64 return None
72 return None 65 return None
(...skipping 19 matching lines...) Expand all
92 if nm_entry and nm_entry['format'] == 'bsd': 85 if nm_entry and nm_entry['format'] == 'bsd':
93 with open(os.path.join(prepared_data_dir, nm_entry['file']), 'r') as f: 86 with open(os.path.join(prepared_data_dir, nm_entry['file']), 'r') as f:
94 static_symbols.load_nm_bsd(f, nm_entry['mangled']) 87 static_symbols.load_nm_bsd(f, nm_entry['mangled'])
95 88
96 readelf_entry = file_entry.get('readelf-e') 89 readelf_entry = file_entry.get('readelf-e')
97 if readelf_entry: 90 if readelf_entry:
98 with open(os.path.join(prepared_data_dir, readelf_entry['file']), 91 with open(os.path.join(prepared_data_dir, readelf_entry['file']),
99 'r') as f: 92 'r') as f:
100 static_symbols.load_readelf_ew(f) 93 static_symbols.load_readelf_ew(f)
101 94
95 decodedline_file_entry = file_entry.get('readelf-debug-decodedline-file')
96 if decodedline_file_entry:
97 with open(os.path.join(prepared_data_dir,
98 decodedline_file_entry['file']), 'r') as f:
99 static_symbols.load_readelf_debug_decodedline_file(f)
100
102 symbols_in_process._static_symbols_in_filse[vma.name] = static_symbols 101 symbols_in_process._static_symbols_in_filse[vma.name] = static_symbols
103 102
104 return symbols_in_process 103 return symbols_in_process
105 104
106 105
107 def _find_runtime_symbols(symbols_in_process, addresses, outputter): 106 def _find_runtime_function_symbols(symbols_in_process, addresses):
107 result = collections.OrderedDict()
108 for address in addresses: 108 for address in addresses:
109 if isinstance(address, basestring): 109 if isinstance(address, basestring):
110 address = int(address, 16) 110 address = int(address, 16)
111 found = symbols_in_process.find_procedure(address) 111 found = symbols_in_process.find_procedure(address)
112 if found: 112 if found:
113 outputter.output(address, found.name) 113 result[address] = found.name
114 else: 114 else:
115 outputter.output(address, '0x%016x' % address) 115 result[address] = '0x%016x' % address
116 return result
116 117
117 118
118 def _find_runtime_typeinfo_symbols(symbols_in_process, addresses, outputter): 119 def _find_runtime_sourcefile_symbols(symbols_in_process, addresses):
120 result = collections.OrderedDict()
121 for address in addresses:
122 if isinstance(address, basestring):
123 address = int(address, 16)
124 found = symbols_in_process.find_sourcefile(address)
125 if found:
126 result[address] = found
127 else:
128 result[address] = ''
129 return result
130
131
132 def _find_runtime_typeinfo_symbols(symbols_in_process, addresses):
133 result = collections.OrderedDict()
119 for address in addresses: 134 for address in addresses:
120 if isinstance(address, basestring): 135 if isinstance(address, basestring):
121 address = int(address, 16) 136 address = int(address, 16)
122 if address == 0: 137 if address == 0:
123 outputter.output(address, 'no typeinfo') 138 result[address] = 'no typeinfo'
124 else: 139 else:
125 found = symbols_in_process.find_typeinfo(address) 140 found = symbols_in_process.find_typeinfo(address)
126 if found: 141 if found:
127 if found.startswith('typeinfo for '): 142 if found.startswith('typeinfo for '):
128 outputter.output(address, found[13:]) 143 result[address] = found[13:]
129 else: 144 else:
130 outputter.output(address, found) 145 result[address] = found
131 else: 146 else:
132 outputter.output(address, '0x%016x' % address) 147 result[address] = '0x%016x' % address
133
134
135 def find_runtime_typeinfo_symbols_list(symbols_in_process, addresses):
136 result = []
137 _find_runtime_typeinfo_symbols(
138 symbols_in_process, addresses, _ListOutput(result))
139 return result 148 return result
140 149
141 150
142 def find_runtime_typeinfo_symbols_dict(symbols_in_process, addresses): 151 _INTERNAL_FINDERS = {
143 result = {} 152 FUNCTION_SYMBOLS: _find_runtime_function_symbols,
144 _find_runtime_typeinfo_symbols( 153 SOURCEFILE_SYMBOLS: _find_runtime_sourcefile_symbols,
145 symbols_in_process, addresses, _DictOutput(result)) 154 TYPEINFO_SYMBOLS: _find_runtime_typeinfo_symbols,
146 return result 155 }
147 156
148 157
149 def find_runtime_typeinfo_symbols_file(symbols_in_process, addresses, f): 158 def find_runtime_symbols(symbol_type, symbols_in_process, addresses):
150 _find_runtime_typeinfo_symbols( 159 return _INTERNAL_FINDERS[symbol_type](symbols_in_process, addresses)
151 symbols_in_process, addresses, _FileOutput(f, False))
152
153
154 def find_runtime_symbols_list(symbols_in_process, addresses):
155 result = []
156 _find_runtime_symbols(symbols_in_process, addresses, _ListOutput(result))
157 return result
158
159
160 def find_runtime_symbols_dict(symbols_in_process, addresses):
161 result = {}
162 _find_runtime_symbols(symbols_in_process, addresses, _DictOutput(result))
163 return result
164
165
166 def find_runtime_symbols_file(symbols_in_process, addresses, f):
167 _find_runtime_symbols(
168 symbols_in_process, addresses, _FileOutput(f, False))
169 160
170 161
171 def main(): 162 def main():
172 # FIX: Accept only .pre data 163 # FIX: Accept only .pre data
173 if len(sys.argv) < 2: 164 if len(sys.argv) < 2:
174 sys.stderr.write("""Usage: 165 sys.stderr.write("""Usage:
175 %s /path/to/prepared_data_dir/ < addresses.txt 166 %s /path/to/prepared_data_dir/ < addresses.txt
176 """ % sys.argv[0]) 167 """ % sys.argv[0])
177 return 1 168 return 1
178 169
179 log = logging.getLogger('find_runtime_symbols') 170 log = logging.getLogger('find_runtime_symbols')
180 log.setLevel(logging.WARN) 171 log.setLevel(logging.WARN)
181 handler = logging.StreamHandler() 172 handler = logging.StreamHandler()
182 handler.setLevel(logging.WARN) 173 handler.setLevel(logging.WARN)
183 formatter = logging.Formatter('%(message)s') 174 formatter = logging.Formatter('%(message)s')
184 handler.setFormatter(formatter) 175 handler.setFormatter(formatter)
185 log.addHandler(handler) 176 log.addHandler(handler)
186 177
187 prepared_data_dir = sys.argv[1] 178 prepared_data_dir = sys.argv[1]
188 if not os.path.exists(prepared_data_dir): 179 if not os.path.exists(prepared_data_dir):
189 log.warn("Nothing found: %s" % prepared_data_dir) 180 log.warn("Nothing found: %s" % prepared_data_dir)
190 return 1 181 return 1
191 if not os.path.isdir(prepared_data_dir): 182 if not os.path.isdir(prepared_data_dir):
192 log.warn("Not a directory: %s" % prepared_data_dir) 183 log.warn("Not a directory: %s" % prepared_data_dir)
193 return 1 184 return 1
194 185
195 symbols_in_process = RuntimeSymbolsInProcess.load(prepared_data_dir) 186 symbols_in_process = RuntimeSymbolsInProcess.load(prepared_data_dir)
196 return find_runtime_symbols_file(symbols_in_process, sys.stdin, sys.stdout) 187 symbols_dict = find_runtime_symbols(FUNCTION_SYMBOLS,
188 symbols_in_process,
189 sys.stdin)
190 for address, symbol in symbols_dict:
191 if symbol:
192 print '%016x %s' % (address, symbol)
193 else:
194 print '%016x' % address
195
196 return 0
197 197
198 198
199 if __name__ == '__main__': 199 if __name__ == '__main__':
200 sys.exit(main()) 200 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698