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

Unified 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: updated 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « tools/find_runtime_symbols/parse_proc_maps.py ('k') | tools/find_runtime_symbols/procedure_boundaries.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/find_runtime_symbols/prepare_symbol_info.py
diff --git a/tools/find_runtime_symbols/prepare_symbol_info.py b/tools/find_runtime_symbols/prepare_symbol_info.py
new file mode 100755
index 0000000000000000000000000000000000000000..57fcfbc3a83d046641379504c93727c61113b911
--- /dev/null
+++ b/tools/find_runtime_symbols/prepare_symbol_info.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import json
+import logging
+import os
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+
+from parse_proc_maps import parse_proc_maps
+from util import executable_condition
+
+
+def prepare_symbol_info(maps_path, output_dir_path=None, loglevel=logging.WARN):
+ log = logging.getLogger('prepare_symbol_info')
+ log.setLevel(loglevel)
+ handler = logging.StreamHandler()
+ handler.setLevel(loglevel)
+ formatter = logging.Formatter('%(message)s')
+ handler.setFormatter(formatter)
+ log.addHandler(handler)
+
+ if not output_dir_path:
+ matched = re.match('^(.*)\.maps$', os.path.basename(maps_path))
+ if matched:
+ output_dir_path = matched.group(1) + '.pre'
+ if not output_dir_path:
+ matched = re.match('^/proc/(.*)/maps$', os.path.realpath(maps_path))
+ if matched:
+ output_dir_path = matched.group(1) + '.pre'
+ if not output_dir_path:
+ output_dir_prefix = os.path.basename(maps_path) + '.pre'
+ # TODO(dmikurube): Find another candidate for output_dir_path.
+
+ log.info('Data for profiling will be collected in "%s".' % output_dir_path)
+ output_dir_path_exists = False
+ if os.path.exists(output_dir_path):
+ if os.path.isdir(output_dir_path) and not os.listdir(output_dir_path):
+ log.warn('Using an empty directory existing at "%s".' % output_dir_path)
+ else:
+ log.warn('A file or a directory exists at "%s".' % output_dir_path)
+ output_dir_path_exists = True
+ else:
+ log.info('Creating a new directory at "%s".' % output_dir_path)
+ os.mkdir(output_dir_path)
+
+ if output_dir_path_exists:
+ return 1
+
+ shutil.copyfile(maps_path, os.path.join(output_dir_path, 'maps'))
+
+ with open(maps_path, mode='r') as f:
+ maps = parse_proc_maps(f)
+
+ log.debug('Listing up symbols.')
+ nm_files = {}
+ for entry in maps.iter(executable_condition):
+ log.debug(' %016x-%016x +%06x %s' % (
+ entry.begin, entry.end, entry.offset, entry.name))
+ with tempfile.NamedTemporaryFile(
+ prefix=os.path.basename(entry.name) + '.',
+ suffix='.nm', delete=False, mode='w', dir=output_dir_path) as f:
+ nm_filename = os.path.realpath(f.name)
+ nm_succeeded = False
+ cppfilt_succeeded = False
+ p_nm = subprocess.Popen(
+ 'nm -n --format bsd %s' % entry.name, shell=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ p_cppfilt = subprocess.Popen(
+ 'c++filt', shell=True,
+ stdin=p_nm.stdout, stdout=f, stderr=subprocess.PIPE)
+
+ if p_nm.wait() == 0:
+ nm_succeeded = True
+ for line in p_nm.stderr:
+ log.debug(line.rstrip())
+ if p_cppfilt.wait() == 0:
+ cppfilt_succeeded = True
+ for line in p_cppfilt.stderr:
+ log.debug(line.rstrip())
+
+ if nm_succeeded and cppfilt_succeeded:
+ nm_files[entry.name] = {
+ 'file': os.path.basename(nm_filename),
+ 'format': 'bsd',
+ 'mangled': False}
+ else:
+ os.remove(nm_filename)
+
+ with open(os.path.join(output_dir_path, 'nm.json'), 'w') as f:
+ json.dump(nm_files, f, indent=2, sort_keys=True)
+
+ log.info('Collected symbol information at "%s".' % output_dir_path)
+ return 0
+
+
+def main():
+ if not sys.platform.startswith('linux'):
+ sys.stderr.write('This script work only on Linux.')
+ return 1
+
+ if len(sys.argv) < 2:
+ sys.stderr.write("""Usage:
+%s /path/to/maps [/path/to/output_data_dir/]
+""" % sys.argv[0])
+ return 1
+ elif len(sys.argv) == 2:
+ sys.exit(prepare_symbol_info(sys.argv[1], loglevel=logging.DEBUG))
+ else:
+ sys.exit(prepare_symbol_info(sys.argv[1], sys.argv[2],
+ loglevel=logging.INFO))
+ return 0
+
+
+if __name__ == '__main__':
+ sys.exit(main())
« no previous file with comments | « tools/find_runtime_symbols/parse_proc_maps.py ('k') | tools/find_runtime_symbols/procedure_boundaries.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698