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

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: update 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):
20 with tempfile.NamedTemporaryFile(
21 prefix=basename + '.', suffix=suffix, delete=False, mode='w',
22 dir=output_dir_path) as f:
23 filename = os.path.realpath(f.name)
24 try:
M-A Ruel 2012/07/27 13:38:14 You should use tempfile.mkstemp() in that case; ha
Dai Mikurube (NOT FULLTIME) 2012/07/30 04:18:38 Done.
25 subprocess.check_call('%s > %s' % (command, filename), shell=True)
26 except:
27 os.remove(filename)
28
29 if os.path.exists(filename) and os.path.getsize(filename) == 0:
30 os.remove(filename)
31 return None
32 if not os.path.exists(filename):
33 return None
34
35 return filename
36
37
19 def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN): 38 def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN):
20 log = logging.getLogger('prepare_symbol_info') 39 log = logging.getLogger('prepare_symbol_info')
21 log.setLevel(loglevel) 40 log.setLevel(loglevel)
22 handler = logging.StreamHandler() 41 handler = logging.StreamHandler()
23 handler.setLevel(loglevel) 42 handler.setLevel(loglevel)
24 formatter = logging.Formatter('%(message)s') 43 formatter = logging.Formatter('%(message)s')
25 handler.setFormatter(formatter) 44 handler.setFormatter(formatter)
26 log.addHandler(handler) 45 log.addHandler(handler)
27 46
28 if not output_dir_path: 47 if not output_dir_path:
(...skipping 22 matching lines...) Expand all
51 70
52 if output_dir_path_exists: 71 if output_dir_path_exists:
53 return 1 72 return 1
54 73
55 shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps')) 74 shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps'))
56 75
57 with open(maps_path, mode='r') as f: 76 with open(maps_path, mode='r') as f:
58 maps = parse_proc_maps(f) 77 maps = parse_proc_maps(f)
59 78
60 log.debug('Listing up symbols.') 79 log.debug('Listing up symbols.')
61 nm_files = {} 80 files = {}
62 for entry in maps.iter(executable_condition): 81 for entry in maps.iter(executable_condition):
63 log.debug(' %016x-%016x +%06x %s' % ( 82 log.debug(' %016x-%016x +%06x %s' % (
64 entry.begin, entry.end, entry.offset, entry.name)) 83 entry.begin, entry.end, entry.offset, entry.name))
65 with tempfile.NamedTemporaryFile( 84 nm_filename = _dump_command_result(
66 prefix=os.path.basename(entry.name) + '.', 85 'nm -n --format bsd %s | c++filt' % entry.name,
M-A Ruel 2012/07/27 13:38:14 Please do not use the shell if possible. You can c
Dai Mikurube (NOT FULLTIME) 2012/07/30 04:18:38 I avoided self-made pipes to avoid subprocess.PIPE
67 suffix='.nm', delete=False, mode='w', dir=output_dir_path) as f: 86 output_dir_path, os.path.basename(entry.name), '.nm')
68 nm_filename = os.path.realpath(f.name) 87 if not nm_filename:
69 nm_succeeded = False 88 continue
70 cppfilt_succeeded = False 89 readelf_e_filename = _dump_command_result(
71 p_nm = subprocess.Popen( 90 'readelf -e %s' % entry.name,
72 'nm -n --format bsd %s' % entry.name, shell=True, 91 output_dir_path, os.path.basename(entry.name), '.readelf-e')
73 stdout=subprocess.PIPE, stderr=subprocess.PIPE) 92 if not readelf_e_filename:
74 p_cppfilt = subprocess.Popen( 93 continue
75 'c++filt', shell=True,
76 stdin=p_nm.stdout, stdout=f, stderr=subprocess.PIPE)
77 94
78 if p_nm.wait() == 0: 95 files[entry.name] = {}
79 nm_succeeded = True 96 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), 97 'file': os.path.basename(nm_filename),
90 'format': 'bsd', 98 'format': 'bsd',
91 'mangled': False} 99 'mangled': False}
92 else: 100 files[entry.name]['readelf-e'] = {
93 os.remove(nm_filename) 101 'file': os.path.basename(readelf_e_filename)}
94 102
95 with open(os.path.join(output_dir_path, 'nm.json'), 'w') as f: 103 with open(os.path.join(output_dir_path, 'files.json'), 'w') as f:
96 json.dump(nm_files, f, indent=2, sort_keys=True) 104 json.dump(files, f, indent=2, sort_keys=True)
97 105
98 log.info('Collected symbol information at "%s".' % output_dir_path) 106 log.info('Collected symbol information at "%s".' % output_dir_path)
99 return 0 107 return 0
100 108
101 109
102 def main(): 110 def main():
103 if not sys.platform.startswith('linux'): 111 if not sys.platform.startswith('linux'):
104 sys.stderr.write('This script work only on Linux.') 112 sys.stderr.write('This script work only on Linux.')
105 return 1 113 return 1
106 114
107 if len(sys.argv) < 2: 115 if len(sys.argv) < 2:
108 sys.stderr.write("""Usage: 116 sys.stderr.write("""Usage:
109 %s /path/to/maps [/path/to/output_data_dir/] 117 %s /path/to/maps [/path/to/output_data_dir/]
110 """ % sys.argv[0]) 118 """ % sys.argv[0])
111 return 1 119 return 1
112 elif len(sys.argv) == 2: 120 elif len(sys.argv) == 2:
113 sys.exit(prepare_symbol_info(sys.argv[1], loglevel=logging.DEBUG)) 121 sys.exit(prepare_symbol_info(sys.argv[1], loglevel=logging.DEBUG))
114 else: 122 else:
115 sys.exit(prepare_symbol_info(sys.argv[1], sys.argv[2], 123 sys.exit(prepare_symbol_info(sys.argv[1], sys.argv[2],
116 loglevel=logging.INFO)) 124 loglevel=logging.INFO))
117 return 0 125 return 0
118 126
119 127
120 if __name__ == '__main__': 128 if __name__ == '__main__':
121 sys.exit(main()) 129 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