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

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

Issue 10795028: A tool for mapping runtime addresses to symbol names. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 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
(Empty)
1 #!/usr/bin/env python
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
4 # found in the LICENSE file.
5
6 import json
7 import logging
8 import os
9 import re
10 import shutil
11 import subprocess
12 import sys
13 import tempfile
14
15 from parse_proc_maps import parse_proc_maps
16 from util import executable_condition
17
18
19 def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN):
20 log = logging.getLogger('prepare_symbol_info')
21 log.setLevel(loglevel)
22 handler = logging.StreamHandler()
23 handler.setLevel(loglevel)
24 formatter = logging.Formatter('%(message)s')
25 handler.setFormatter(formatter)
26 log.addHandler(handler)
27
28 if not output_dir_path:
29 matched = re.match('^(.*)\.maps$', os.path.basename(maps_path))
30 if matched:
31 output_dir_path = matched.group(1) + '.pre'
32 if not output_dir_path:
33 matched = re.match('^/proc/(.*)/maps$', os.path.realpath(maps_path))
34 if matched:
35 output_dir_path = matched.group(1) + '.pre'
36 if not output_dir_path:
37 output_dir_prefix = os.path.basename(maps_path) + '.pre'
38 # TODO(dmikurube): Find another candidate for output_dir_path.
39
40 log.info('Data for profiling will be collected in "%s".' % output_dir_path)
41 output_dir_path_exists = False
42 if os.path.exists(output_dir_path):
43 if os.path.isdir(output_dir_path) and not os.listdir(output_dir_path):
44 log.warn('Using an empty directory existing at "%s".' % output_dir_path)
45 else:
46 log.warn('A file or a directory exists at "%s".' % output_dir_path)
47 output_dir_path_exists = True
48 else:
49 log.info('Creating a new directory at "%s".' % output_dir_path)
50 os.mkdir(output_dir_path)
51
52 if output_dir_path_exists:
53 return 1
54
55 shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps'))
56
57 with open(maps_path, mode='r') as f:
M-A Ruel 2012/07/20 14:10:21 optional: mode='r' is the default so it is optiona
Dai Mikurube (NOT FULLTIME) 2012/07/21 04:50:10 Thanks. I keep it as is to make it clear that it'
58 maps = parse_proc_maps(f)
59
60 log.debug('Listing up symbols.')
61 nm_files = {}
62 for entry in maps.iter(executable_condition):
63 log.debug(' %016x-%016x +%06x %s' % (
64 entry.begin, entry.end, entry.offset, entry.name))
65 with tempfile.NamedTemporaryFile(
66 prefix=os.path.basename(entry.name) + '.',
67 suffix='.nm', delete=False, mode='w', dir=output_dir_path) as f:
68 nm_filename = os.path.realpath(f.name)
69 nm_succeeded = False
70 cppfilt_succeeded = False
71 p_nm = subprocess.Popen(
72 'nm -n --format bsd %s' % entry.name, shell=True,
73 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
74 p_cppfilt = subprocess.Popen(
75 'c++filt', shell=True,
76 stdin=p_nm.stdout, stdout=f, stderr=subprocess.PIPE)
77
78 if p_nm.wait() == 0:
79 nm_succeeded = True
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),
90 'format': 'bsd',
91 'mangled': False}
92 else:
93 os.remove(nm_filename)
94
95 with open(os.path.join(output_dir_path, 'nm.json'), 'w') as f:
96 json.dump(nm_files, f, indent=2, sort_keys=True)
97
98 log.info('Collected symbol information at "%s".' % output_dir_path)
99 return 0
100
101
102 def main():
103 if not sys.platform.startswith('linux'):
104 sys.stderr.write('This script work only on Linux.')
105 return 1
106
107 if len(sys.argv) < 2:
108 sys.stderr.write("""Usage:
109 %s /path/to/maps [/path/to/output_data_dir/]
110 """ % sys.argv[0])
111 return 1
112 elif len(sys.argv) == 2:
113 sys.exit(prepare_symbol_info(sys.argv[1], loglevel=logging.DEBUG))
114 else:
115 sys.exit(prepare_symbol_info(sys.argv[1], sys.argv[2],
116 loglevel=logging.INFO))
117 return 0
118
119
120 if __name__ == '__main__':
121 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698