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

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

Issue 10826008: Load static symbol information lazily with some clean-ups. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: refine Created 8 years, 4 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 5
6 import json 6 import json
7 import logging 7 import logging
8 import os 8 import os
9 import re 9 import re
10 import shutil 10 import shutil
11 import subprocess 11 import subprocess
12 import sys 12 import sys
13 import tempfile 13 import tempfile
14 14
15 from parse_proc_maps import parse_proc_maps 15 from parse_proc_maps import parse_proc_maps
16 from util import executable_condition 16 from util import executable_condition
17 17
18 18
19 def _dump_command_result(command, output_dir_path, basename, suffix, log):
20 handle_out, filename_out = tempfile.mkstemp(
21 suffix=suffix, prefix=basename + '.', dir=output_dir_path)
22 handle_err, filename_err = tempfile.mkstemp(
23 suffix=suffix + '.err', prefix=basename + '.', dir=output_dir_path)
24 error = False
25 try:
26 subprocess.check_call(
27 command, stdout=handle_out, stderr=handle_err, shell=True)
28 except:
29 error = True
30 finally:
31 os.close(handle_err)
32 os.close(handle_out)
33
34 if os.path.exists(filename_err):
35 if log.getEffectiveLevel() <= logging.DEBUG:
36 with open(filename_err, 'r') as f:
37 for line in f:
38 log.debug(line.rstrip())
39 os.remove(filename_err)
40
41 if os.path.exists(filename_out) and (
42 os.path.getsize(filename_out) == 0 or error):
43 os.remove(filename_out)
44 return None
45
46 if not os.path.exists(filename_out):
47 return None
48
49 return filename_out
50
51
19 def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN): 52 def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN):
20 log = logging.getLogger('prepare_symbol_info') 53 log = logging.getLogger('prepare_symbol_info')
21 log.setLevel(loglevel) 54 log.setLevel(loglevel)
22 handler = logging.StreamHandler() 55 handler = logging.StreamHandler()
23 handler.setLevel(loglevel) 56 handler.setLevel(loglevel)
24 formatter = logging.Formatter('%(message)s') 57 formatter = logging.Formatter('%(message)s')
25 handler.setFormatter(formatter) 58 handler.setFormatter(formatter)
26 log.addHandler(handler) 59 log.addHandler(handler)
27 60
28 if not output_dir_path: 61 if not output_dir_path:
(...skipping 22 matching lines...) Expand all
51 84
52 if output_dir_path_exists: 85 if output_dir_path_exists:
53 return 1 86 return 1
54 87
55 shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps')) 88 shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps'))
56 89
57 with open(maps_path, mode='r') as f: 90 with open(maps_path, mode='r') as f:
58 maps = parse_proc_maps(f) 91 maps = parse_proc_maps(f)
59 92
60 log.debug('Listing up symbols.') 93 log.debug('Listing up symbols.')
61 nm_files = {} 94 files = {}
62 for entry in maps.iter(executable_condition): 95 for entry in maps.iter(executable_condition):
63 log.debug(' %016x-%016x +%06x %s' % ( 96 log.debug(' %016x-%016x +%06x %s' % (
64 entry.begin, entry.end, entry.offset, entry.name)) 97 entry.begin, entry.end, entry.offset, entry.name))
65 with tempfile.NamedTemporaryFile( 98 nm_filename = _dump_command_result(
66 prefix=os.path.basename(entry.name) + '.', 99 'nm -n --format bsd %s | c++filt' % entry.name,
67 suffix='.nm', delete=False, mode='w', dir=output_dir_path) as f: 100 output_dir_path, os.path.basename(entry.name), '.nm', log)
68 nm_filename = os.path.realpath(f.name) 101 if not nm_filename:
69 nm_succeeded = False 102 continue
70 cppfilt_succeeded = False 103 readelf_e_filename = _dump_command_result(
71 p_nm = subprocess.Popen( 104 'readelf -e %s' % entry.name,
72 'nm -n --format bsd %s' % entry.name, shell=True, 105 output_dir_path, os.path.basename(entry.name), '.readelf-e', log)
73 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 106 if not readelf_e_filename:
74 p_cppfilt = subprocess.Popen( 107 continue
75 'c++filt', shell=True,
76 stdin=p_nm.stdout, stdout=f, stderr=subprocess.PIPE)
77 108
78 if p_nm.wait() == 0: 109 files[entry.name] = {}
79 nm_succeeded = True 110 files[entry.name]['nm'] = {
80 for line in p_nm.stderr:
81 log.debug(line.rstrip())
82 if p_cppfilt.wait() == 0:
83 cppfilt_succeeded = True
84 for line in p_cppfilt.stderr:
85 log.debug(line.rstrip())
86
87 if nm_succeeded and cppfilt_succeeded:
88 nm_files[entry.name] = {
89 'file': os.path.basename(nm_filename), 111 'file': os.path.basename(nm_filename),
90 'format': 'bsd', 112 'format': 'bsd',
91 'mangled': False} 113 'mangled': False}
92 else: 114 files[entry.name]['readelf-e'] = {
93 os.remove(nm_filename) 115 'file': os.path.basename(readelf_e_filename)}
94 116
95 with open(os.path.join(output_dir_path, 'nm.json'), 'w') as f: 117 with open(os.path.join(output_dir_path, 'files.json'), 'w') as f:
96 json.dump(nm_files, f, indent=2, sort_keys=True) 118 json.dump(files, f, indent=2, sort_keys=True)
97 119
98 log.info('Collected symbol information at "%s".' % output_dir_path) 120 log.info('Collected symbol information at "%s".' % output_dir_path)
99 return 0 121 return 0
100 122
101 123
102 def main(): 124 def main():
103 if not sys.platform.startswith('linux'): 125 if not sys.platform.startswith('linux'):
104 sys.stderr.write('This script work only on Linux.') 126 sys.stderr.write('This script work only on Linux.')
105 return 1 127 return 1
106 128
107 if len(sys.argv) < 2: 129 if len(sys.argv) < 2:
108 sys.stderr.write("""Usage: 130 sys.stderr.write("""Usage:
109 %s /path/to/maps [/path/to/output_data_dir/] 131 %s /path/to/maps [/path/to/output_data_dir/]
110 """ % sys.argv[0]) 132 """ % sys.argv[0])
111 return 1 133 return 1
112 elif len(sys.argv) == 2: 134 elif len(sys.argv) == 2:
113 sys.exit(prepare_symbol_info(sys.argv[1], loglevel=logging.DEBUG)) 135 sys.exit(prepare_symbol_info(sys.argv[1], loglevel=logging.INFO))
114 else: 136 else:
115 sys.exit(prepare_symbol_info(sys.argv[1], sys.argv[2], 137 sys.exit(prepare_symbol_info(sys.argv[1], sys.argv[2],
116 loglevel=logging.INFO)) 138 loglevel=logging.INFO))
117 return 0 139 return 0
118 140
119 141
120 if __name__ == '__main__': 142 if __name__ == '__main__':
121 sys.exit(main()) 143 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/find_runtime_symbols/find_runtime_symbols.py ('k') | tools/find_runtime_symbols/procedure_boundaries.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698