summaryrefslogtreecommitdiffstats
path: root/tools/find_runtime_symbols
diff options
context:
space:
mode:
authordmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-03 06:32:40 +0000
committerdmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-03 06:32:40 +0000
commitc6400ce9269d39d5b413c9b17a55f8ff1840456a (patch)
treef6620ef5dcc36d4be9cd84468545b0fe43df9f92 /tools/find_runtime_symbols
parentd42144308fc22012382756ff5c4295ab78b3f0fe (diff)
downloadchromium_src-c6400ce9269d39d5b413c9b17a55f8ff1840456a.zip
chromium_src-c6400ce9269d39d5b413c9b17a55f8ff1840456a.tar.gz
chromium_src-c6400ce9269d39d5b413c9b17a55f8ff1840456a.tar.bz2
Add hints to find source file names from runtime virtual addresses.
prepare_symbol_info.py collected symbol and elf mapping information from binaries. This patch adds another set of hints to find source file names from DWARF .debug_line information with readelf. reduce_debugline.py picks up only address ranges from the original readelf output since the original output is too large. See the test how it works. BUG=225343 NOTRY=true Review URL: https://chromiumcodereview.appspot.com/13261014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192004 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/find_runtime_symbols')
-rwxr-xr-xtools/find_runtime_symbols/prepare_symbol_info.py8
-rwxr-xr-xtools/find_runtime_symbols/reduce_debugline.py85
-rwxr-xr-xtools/find_runtime_symbols/tests/reduce_debugline_test.py137
3 files changed, 230 insertions, 0 deletions
diff --git a/tools/find_runtime_symbols/prepare_symbol_info.py b/tools/find_runtime_symbols/prepare_symbol_info.py
index 9b16225..5289cb8 100755
--- a/tools/find_runtime_symbols/prepare_symbol_info.py
+++ b/tools/find_runtime_symbols/prepare_symbol_info.py
@@ -15,6 +15,8 @@ import tempfile
from proc_maps import ProcMaps
+BASE_PATH = os.path.dirname(os.path.abspath(__file__))
+REDUCE_DEBUGLINE_PATH = os.path.join(BASE_PATH, 'reduce_debugline.py')
LOGGER = logging.getLogger('prepare_symbol_info')
@@ -142,6 +144,9 @@ def prepare_symbol_info(maps_path, output_dir_path=None, use_tempdir=False):
output_dir_path, os.path.basename(entry.name), '.readelf-e')
if not readelf_e_filename:
continue
+ readelf_reduced_debugline_filename = _dump_command_result(
+ 'readelf -wLW %s | %s' % (entry.name, REDUCE_DEBUGLINE_PATH),
+ output_dir_path, os.path.basename(entry.name), '.readelf-debugline')
files[entry.name] = {}
files[entry.name]['nm'] = {
@@ -150,6 +155,9 @@ def prepare_symbol_info(maps_path, output_dir_path=None, use_tempdir=False):
'mangled': False}
files[entry.name]['readelf-e'] = {
'file': os.path.basename(readelf_e_filename)}
+ if readelf_reduced_debugline_filename:
+ files[entry.name]['readelf-reduced-debugline'] = {
+ 'file': os.path.basename(readelf_reduced_debugline_filename)}
with open(os.path.join(output_dir_path, 'files.json'), 'w') as f:
json.dump(files, f, indent=2, sort_keys=True)
diff --git a/tools/find_runtime_symbols/reduce_debugline.py b/tools/find_runtime_symbols/reduce_debugline.py
new file mode 100755
index 0000000..1a4efaa
--- /dev/null
+++ b/tools/find_runtime_symbols/reduce_debugline.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+# Copyright (c) 2013 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.
+"""Reduces result of 'readelf -wL' to just a set of address ranges per file.
+
+For example:
+
+CU: ../../chrome_main.cc:
+File name Line number Starting address
+chrome_main.cc 30 0xa3be90
+(an empty line)
+chrome_main.cc 31 0xa3bea3
+chrome_main.cc 32 0xa3beaf
+chrome_main.cc 34 0xa3bec9
+chrome_main.cc 32 0xa3bed1
+(an empty line)
+
+The example above is reduced into:
+{'../../chrome_main.cc', [(0xa3be90, 0xa3be90), (0xa3bea3, 0xa3bed1)]}
+where (0xa3bea3, 0xa3bed1) means an address range from 0xa3bea3 to 0xa3bed1.
+
+This script assumes that the result of 'readelf -wL' ends with an empty line.
+
+Note: the option '-wL' has the same meaning with '--debug-dump=decodedline'.
+"""
+
+import re
+import sys
+
+
+_FILENAME_PATTERN = re.compile('(CU: |)(.+)\:')
+
+
+def reduce_decoded_debugline(input_file):
+ filename = ''
+ ranges_dict = {}
+ starting = None
+ ending = None
+
+ for line in input_file:
+ line = line.strip()
+
+ if line.endswith(':'):
+ matched = _FILENAME_PATTERN.match(line)
+ if matched:
+ filename = matched.group(2)
+ continue
+
+ unpacked = line.split(None, 2)
+ if len(unpacked) != 3 or not unpacked[2].startswith('0x'):
+ if starting:
+ ranges_dict.setdefault(filename, []).append((starting, ending))
+ starting = None
+ ending = None
+ continue
+
+ ending = int(unpacked[2], 16)
+ if not starting:
+ starting = ending
+
+ if starting or ending:
+ raise ValueError('No new line at last.')
+
+ return ranges_dict
+
+
+def main():
+ if len(sys.argv) != 1:
+ print >> sys.stderr, 'Unsupported arguments'
+ return 1
+
+ ranges_dict = reduce_decoded_debugline(sys.stdin)
+ for filename, ranges in ranges_dict.iteritems():
+ print filename + ':'
+ prev = (0, 0)
+ for address_range in sorted(ranges):
+ if address_range == prev:
+ continue
+ print ' %x-%x' % (address_range[0], address_range[1])
+ prev = address_range
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/find_runtime_symbols/tests/reduce_debugline_test.py b/tools/find_runtime_symbols/tests/reduce_debugline_test.py
new file mode 100755
index 0000000..04488a5
--- /dev/null
+++ b/tools/find_runtime_symbols/tests/reduce_debugline_test.py
@@ -0,0 +1,137 @@
+#!/usr/bin/env python
+# Copyright (c) 2013 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 cStringIO
+import logging
+import os
+import sys
+import textwrap
+import unittest
+
+ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+sys.path.insert(0, ROOT_DIR)
+
+import reduce_debugline
+
+
+class ReduceDebuglineTest(unittest.TestCase):
+ _DECODED_DEBUGLINE = textwrap.dedent("""\
+ Decoded dump of debug contents of section .debug_line:
+
+ CU: ../../chrome/app/chrome_exe_main_gtk.cc:
+ File name Line number Starting address
+ chrome_exe_main_gtk.cc 33 0xa3be50
+
+ chrome_exe_main_gtk.cc 34 0xa3be66
+ chrome_exe_main_gtk.cc 39 0xa3be75
+ chrome_exe_main_gtk.cc 42 0xa3be7a
+
+ CU: ../../chrome/app/chrome_main.cc:
+ File name Line number Starting address
+ chrome_main.cc 30 0xa3be90
+
+ chrome_main.cc 31 0xa3bea3
+ chrome_main.cc 32 0xa3beaf
+ chrome_main.cc 34 0xa3bec9
+ chrome_main.cc 32 0xa3bed1
+
+ CU: ../../chrome/app/chrome_main_delegate.cc:
+ File name Line number Starting address
+ chrome_main_delegate.cc 320 0xa3bee0
+
+ chrome_main_delegate.cc 320 0xa3bef0
+ chrome_main_delegate.cc 321 0xa3bf43
+ chrome_main_delegate.cc 322 0xa3bf48
+ chrome_main_delegate.cc 324 0xa3bf50
+ chrome_main_delegate.cc 324 0xa3bf60
+
+ chrome_main_delegate.cc 612 0xa3cd54
+ chrome_main_delegate.cc 617 0xa3cd6b
+ chrome_main_delegate.cc 299 0xa3d5fd
+ chrome_main_delegate.cc 300 0xa3d605
+
+ ../../content/public/app/content_main_delegate.h:
+ content_main_delegate.h 22 0xa3d620
+
+ content_main_delegate.h 22 0xa3d637
+
+ ../../chrome/common/chrome_content_client.h:
+ chrome_content_client.h 16 0xa3d640
+
+ chrome_content_client.h 16 0xa3d650
+
+ ../../base/memory/scoped_ptr.h:
+ scoped_ptr.h 323 0xa3d680
+
+ scoped_ptr.h 323 0xa3d690
+
+ ../../base/memory/scoped_ptr.h:
+ scoped_ptr.h 323 0xa3d660
+
+ scoped_ptr.h 323 0xa3d670
+
+ ../../base/memory/scoped_ptr.h:
+ scoped_ptr.h 428 0xa3d6a0
+
+ scoped_ptr.h 428 0xa3d6b0
+
+ CU: ../../something.c:
+ File name Line number Starting address
+ something.c 57 0x76e2cc0
+
+ something.c 62 0x76e2cd3
+ something.c 64 0x76e2cda
+ something.c 65 0x76e2ce9
+ something.c 66 0x76e2cf8
+
+ """)
+
+ _EXPECTED_REDUCED_DEBUGLINE = {
+ '../../chrome/app/chrome_exe_main_gtk.cc': [
+ (0xa3be50, 0xa3be50),
+ (0xa3be66, 0xa3be7a),
+ ],
+ '../../chrome/app/chrome_main.cc': [
+ (0xa3be90, 0xa3be90),
+ (0xa3bea3, 0xa3bed1),
+ ],
+ '../../chrome/app/chrome_main_delegate.cc': [
+ (0xa3bee0, 0xa3bee0),
+ (0xa3bef0, 0xa3bf60),
+ (0xa3cd54, 0xa3d605),
+ ],
+ '../../content/public/app/content_main_delegate.h': [
+ (0xa3d620, 0xa3d620),
+ (0xa3d637, 0xa3d637),
+ ],
+ '../../chrome/common/chrome_content_client.h': [
+ (0xa3d640, 0xa3d640),
+ (0xa3d650, 0xa3d650),
+ ],
+ '../../base/memory/scoped_ptr.h': [
+ (0xa3d680, 0xa3d680),
+ (0xa3d690, 0xa3d690),
+ (0xa3d660, 0xa3d660),
+ (0xa3d670, 0xa3d670),
+ (0xa3d6a0, 0xa3d6a0),
+ (0xa3d6b0, 0xa3d6b0),
+ ],
+ '../../something.c': [
+ (0x76e2cc0, 0x76e2cc0),
+ (0x76e2cd3, 0x76e2cf8),
+ ],
+ }
+
+ def test(self):
+ ranges_dict = reduce_debugline.reduce_decoded_debugline(
+ cStringIO.StringIO(self._DECODED_DEBUGLINE))
+ self.assertEqual(self._EXPECTED_REDUCED_DEBUGLINE, ranges_dict)
+
+
+if __name__ == '__main__':
+ logging.basicConfig(
+ level=logging.DEBUG if '-v' in sys.argv else logging.ERROR,
+ format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
+ unittest.main()