diff options
author | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-21 12:33:51 +0000 |
---|---|---|
committer | dmikurube@chromium.org <dmikurube@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-21 12:33:51 +0000 |
commit | f45a5f17a7cd4b7819f59fd0048cf6f6f37113b0 (patch) | |
tree | 393e6d75ade34d7cc2c83e8973e779d7bdfd5ed6 /tools/find_runtime_symbols | |
parent | e1937eeca85096cddded0e024bfd513ba2f7d172 (diff) | |
download | chromium_src-f45a5f17a7cd4b7819f59fd0048cf6f6f37113b0.zip chromium_src-f45a5f17a7cd4b7819f59fd0048cf6f6f37113b0.tar.gz chromium_src-f45a5f17a7cd4b7819f59fd0048cf6f6f37113b0.tar.bz2 |
Add a first test for tools/find_runtime_symbols.
BUG=123749
Review URL: https://chromiumcodereview.appspot.com/11299095
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@169023 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/find_runtime_symbols')
-rw-r--r-- | tools/find_runtime_symbols/PRESUBMIT.py | 45 | ||||
-rwxr-xr-x | tools/find_runtime_symbols/find_runtime_symbols.py | 32 | ||||
-rwxr-xr-x | tools/find_runtime_symbols/prepare_symbol_info.py | 4 | ||||
-rw-r--r-- | tools/find_runtime_symbols/proc_maps.py | 32 | ||||
-rw-r--r-- | tools/find_runtime_symbols/static_symbols.py | 8 | ||||
-rwxr-xr-x | tools/find_runtime_symbols/tests/proc_maps_test.py | 110 |
6 files changed, 201 insertions, 30 deletions
diff --git a/tools/find_runtime_symbols/PRESUBMIT.py b/tools/find_runtime_symbols/PRESUBMIT.py new file mode 100644 index 0000000..8d6889c --- /dev/null +++ b/tools/find_runtime_symbols/PRESUBMIT.py @@ -0,0 +1,45 @@ +# 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. + +"""Top-level presubmit script for find_runtime_symbols. + +See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for +details on the presubmit API built into gcl. +""" + + +def CommonChecks(input_api, output_api): + import sys + def join(*args): + return input_api.os_path.join(input_api.PresubmitLocalPath(), *args) + + output = [] + sys_path_backup = sys.path + try: + sys.path = [ + join('..', 'find_runtime_symbols'), + ] + sys.path + output.extend(input_api.canned_checks.RunPylint(input_api, output_api)) + finally: + sys.path = sys_path_backup + + output.extend( + input_api.canned_checks.RunUnitTestsInDirectory( + input_api, output_api, + input_api.os_path.join(input_api.PresubmitLocalPath(), 'tests'), + whitelist=[r'.+_test\.py$'])) + + if input_api.is_committing: + output.extend(input_api.canned_checks.PanProjectChecks(input_api, + output_api, + owners_check=False)) + return output + + +def CheckChangeOnUpload(input_api, output_api): + return CommonChecks(input_api, output_api) + + +def CheckChangeOnCommit(input_api, output_api): + return CommonChecks(input_api, output_api) diff --git a/tools/find_runtime_symbols/find_runtime_symbols.py b/tools/find_runtime_symbols/find_runtime_symbols.py index 8693533..57c83f5 100755 --- a/tools/find_runtime_symbols/find_runtime_symbols.py +++ b/tools/find_runtime_symbols/find_runtime_symbols.py @@ -6,7 +6,6 @@ import json import logging import os -import re import sys from static_symbols import StaticSymbolsInFile @@ -21,7 +20,7 @@ class _ListOutput(object): def __init__(self, result): self.result = result - def output(self, address, symbol): + def output(self, address, symbol): # pylint: disable=W0613 self.result.append(symbol) @@ -81,6 +80,7 @@ class RuntimeSymbolsInProcess(object): with open(os.path.join(prepared_data_dir, _FILES_FILENAME), mode='r') as f: files = json.load(f) + # pylint: disable=W0212 for vma in symbols_in_process._maps.iter(ProcMaps.executable_and_constants): file_entry = files.get(vma.name) if not file_entry: @@ -132,38 +132,40 @@ def _find_runtime_typeinfo_symbols(symbols_in_process, addresses, outputter): outputter.output(address, '0x%016x' % address) -def find_runtime_typeinfo_symbols_list(static_symbols, addresses): +def find_runtime_typeinfo_symbols_list(symbols_in_process, addresses): result = [] - _find_runtime_typeinfo_symbols(static_symbols, addresses, _ListOutput(result)) + _find_runtime_typeinfo_symbols( + symbols_in_process, addresses, _ListOutput(result)) return result -def find_runtime_typeinfo_symbols_dict(static_symbols, addresses): +def find_runtime_typeinfo_symbols_dict(symbols_in_process, addresses): result = {} - _find_runtime_typeinfo_symbols(static_symbols, addresses, _DictOutput(result)) + _find_runtime_typeinfo_symbols( + symbols_in_process, addresses, _DictOutput(result)) return result -def find_runtime_typeinfo_symbols_file(static_symbols, addresses, f): +def find_runtime_typeinfo_symbols_file(symbols_in_process, addresses, f): _find_runtime_typeinfo_symbols( - static_symbols, addresses, _FileOutput(f, False)) + symbols_in_process, addresses, _FileOutput(f, False)) -def find_runtime_symbols_list(static_symbols, addresses): +def find_runtime_symbols_list(symbols_in_process, addresses): result = [] - _find_runtime_symbols(static_symbols, addresses, _ListOutput(result)) + _find_runtime_symbols(symbols_in_process, addresses, _ListOutput(result)) return result -def find_runtime_symbols_dict(static_symbols, addresses): +def find_runtime_symbols_dict(symbols_in_process, addresses): result = {} - _find_runtime_symbols(static_symbols, addresses, _DictOutput(result)) + _find_runtime_symbols(symbols_in_process, addresses, _DictOutput(result)) return result -def find_runtime_symbols_file(static_symbols, addresses, f): +def find_runtime_symbols_file(symbols_in_process, addresses, f): _find_runtime_symbols( - static_symbols, addresses, _FileOutput(f, False)) + symbols_in_process, addresses, _FileOutput(f, False)) def main(): @@ -191,7 +193,7 @@ def main(): return 1 symbols_in_process = RuntimeSymbolsInProcess.load(prepared_data_dir) - return find_runtime_symbols_file(static_symbols, sys.stdin, sys.stdout) + return find_runtime_symbols_file(symbols_in_process, sys.stdin, sys.stdout) if __name__ == '__main__': diff --git a/tools/find_runtime_symbols/prepare_symbol_info.py b/tools/find_runtime_symbols/prepare_symbol_info.py index 0723de3..9b16225 100755 --- a/tools/find_runtime_symbols/prepare_symbol_info.py +++ b/tools/find_runtime_symbols/prepare_symbol_info.py @@ -27,7 +27,7 @@ def _dump_command_result(command, output_dir_path, basename, suffix): try: subprocess.check_call( command, stdout=handle_out, stderr=handle_err, shell=True) - except: + except (OSError, subprocess.CalledProcessError): error = True finally: os.close(handle_err) @@ -112,7 +112,7 @@ def prepare_symbol_info(maps_path, output_dir_path=None, use_tempdir=False): LOGGER.info('Creating a new directory "%s".' % output_dir_path) try: os.mkdir(output_dir_path) - except OSError, e: + except OSError: LOGGER.warn('A directory "%s" cannot be created.' % output_dir_path) if use_tempdir: output_dir_path = tempfile.mkdtemp() diff --git a/tools/find_runtime_symbols/proc_maps.py b/tools/find_runtime_symbols/proc_maps.py index 4b082c3..6e1434c 100644 --- a/tools/find_runtime_symbols/proc_maps.py +++ b/tools/find_runtime_symbols/proc_maps.py @@ -3,12 +3,11 @@ # found in the LICENSE file. import re -import sys _MAPS_PATTERN = re.compile( '^([a-f0-9]+)-([a-f0-9]+)\s+(.)(.)(.)(.)\s+([a-f0-9]+)\s+(\S+):(\S+)\s+' - '(\d+)\s+(\S+)$', re.IGNORECASE) + '(\d+)\s*(.*)$', re.IGNORECASE) class ProcMapsEntry(object): @@ -29,6 +28,21 @@ class ProcMapsEntry(object): self.inode = inode self.name = name + def as_dict(self): + return { + 'begin': self.begin, + 'end': self.end, + 'readable': self.readable, + 'writable': self.writable, + 'executable': self.executable, + 'private': self.private, + 'offset': self.offset, + 'major': self.major, + 'minor': self.minor, + 'inode': self.inode, + 'name': self.name, + } + class ProcMaps(object): """A class representing contents in /proc/.../maps.""" @@ -38,12 +52,6 @@ class ProcMaps(object): self._dictionary = {} self._sorted = True - def append(self, entry): - if self._sorted_indexes and self._sorted_indexes[-1] > entry.begin: - self._sorted = False - self._sorted_indexes.append(entry.begin) - self._dictionary[entry.begin] = entry - def iter(self, condition): if not self._sorted: self._sorted_indexes.sort() @@ -65,7 +73,7 @@ class ProcMaps(object): for line in f: matched = _MAPS_PATTERN.match(line) if matched: - table.append(ProcMapsEntry( + table._append(ProcMapsEntry( # pylint: disable=W0212 int(matched.group(1), 16), # begin int(matched.group(2), 16), # end matched.group(3), # readable @@ -99,3 +107,9 @@ class ProcMaps(object): entry.executable == 'x') and re.match( '\S+(\.(so|dll|dylib|bundle)|chrome)((\.\d+)+\w*(\.\d+){0,3})?', entry.name)) + + def _append(self, entry): + if self._sorted_indexes and self._sorted_indexes[-1] > entry.begin: + self._sorted = False + self._sorted_indexes.append(entry.begin) + self._dictionary[entry.begin] = entry diff --git a/tools/find_runtime_symbols/static_symbols.py b/tools/find_runtime_symbols/static_symbols.py index eb943e1..e972ad7 100644 --- a/tools/find_runtime_symbols/static_symbols.py +++ b/tools/find_runtime_symbols/static_symbols.py @@ -3,9 +3,7 @@ # found in the LICENSE file. import bisect -import os import re -import sys _ARGUMENT_TYPE_PATTERN = re.compile('\([^()]*\)(\s*const)?') @@ -185,14 +183,16 @@ class StaticSymbolsInFile(object): if line in ('Key to Flags:', 'Program Headers:'): break - def _parse_nm_bsd_line(self, line): + @staticmethod + def _parse_nm_bsd_line(line): if line[8] == ' ': return line[0:8], line[9], line[11:] elif line[16] == ' ': return line[0:16], line[17], line[19:] raise ParsingException('Invalid nm output.') - def _get_short_function_name(self, function): + @staticmethod + def _get_short_function_name(function): while True: function, number = _ARGUMENT_TYPE_PATTERN.subn('', function) if not number: diff --git a/tools/find_runtime_symbols/tests/proc_maps_test.py b/tools/find_runtime_symbols/tests/proc_maps_test.py new file mode 100755 index 0000000..502f252 --- /dev/null +++ b/tools/find_runtime_symbols/tests/proc_maps_test.py @@ -0,0 +1,110 @@ +#!/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 cStringIO +import logging +import os +import sys +import unittest + +ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +sys.path.insert(0, ROOT_DIR) + +from proc_maps import ProcMaps + + +class ProcMapsTest(unittest.TestCase): + _TEST_PROCMAPS = '\n'.join([ + '00000000-00001000 r--p 00000000 fc:00 0', + '0080b000-0080c000 r-xp 0020b000 fc:00 2231329' + ' /usr/bin/some', + '0080c000-0080f000 ---p 0020c000 fc:00 2231329' + ' /usr/bin/some', + '0100a000-0100c000 r-xp 0120a000 fc:00 22381' + ' /usr/bin/chrome', + '0100c000-0100f000 ---p 0120c000 fc:00 22381' + ' /usr/bin/chrome', + '0237d000-02a9b000 rw-p 00000000 00:00 0' + ' [heap]', + '7fb920e6d000-7fb920e85000 r-xp 00000000 fc:00 263482' + ' /lib/x86_64-linux-gnu/libpthread-2.15.so', + '7fb920e85000-7fb921084000 ---p 00018000 fc:00 263482' + ' /lib/x86_64-linux-gnu/libpthread-2.15.so', + '7fb9225f4000-7fb922654000 rw-s 00000000 00:04 19660808' + ' /SYSV00000000 (deleted)', + 'ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0' + ' [vsyscall]', + ]) + + _EXPECTED = [ + (0x0, 0x1000, 'r', '-', '-', 'p', 0x0, 'fc', '00', 0, ''), + (0x80b000, 0x80c000, 'r', '-', 'x', 'p', 0x20b000, + 'fc', '00', 2231329, '/usr/bin/some'), + (0x80c000, 0x80f000, '-', '-', '-', 'p', 0x20c000, + 'fc', '00', 2231329, '/usr/bin/some'), + (0x100a000, 0x100c000, 'r', '-', 'x', 'p', 0x120a000, + 'fc', '00', 22381, '/usr/bin/chrome'), + (0x100c000, 0x100f000, '-', '-', '-', 'p', 0x120c000, + 'fc', '00', 22381, '/usr/bin/chrome'), + (0x237d000, 0x2a9b000, 'r', 'w', '-', 'p', 0x0, + '00', '00', 0, '[heap]'), + (0x7fb920e6d000, 0x7fb920e85000, 'r', '-', 'x', 'p', 0x0, + 'fc', '00', 263482, '/lib/x86_64-linux-gnu/libpthread-2.15.so'), + (0x7fb920e85000, 0x7fb921084000, '-', '-', '-', 'p', 0x18000, + 'fc', '00', 263482, '/lib/x86_64-linux-gnu/libpthread-2.15.so'), + (0x7fb9225f4000, 0x7fb922654000, 'r', 'w', '-', 's', 0x0, + '00', '04', 19660808, '/SYSV00000000 (deleted)'), + (0xffffffffff600000, 0xffffffffff601000, 'r', '-', 'x', 'p', 0x0, + '00', '00', 0, '[vsyscall]'), + ] + + @staticmethod + def _expected_as_dict(index): + return { + 'begin': ProcMapsTest._EXPECTED[index][0], + 'end': ProcMapsTest._EXPECTED[index][1], + 'readable': ProcMapsTest._EXPECTED[index][2], + 'writable': ProcMapsTest._EXPECTED[index][3], + 'executable': ProcMapsTest._EXPECTED[index][4], + 'private': ProcMapsTest._EXPECTED[index][5], + 'offset': ProcMapsTest._EXPECTED[index][6], + 'major': ProcMapsTest._EXPECTED[index][7], + 'minor': ProcMapsTest._EXPECTED[index][8], + 'inode': ProcMapsTest._EXPECTED[index][9], + 'name': ProcMapsTest._EXPECTED[index][10], + } + + def test_load(self): + maps = ProcMaps.load(cStringIO.StringIO(self._TEST_PROCMAPS)) + for index, entry in enumerate(maps): + self.assertEqual(entry.as_dict(), self._expected_as_dict(index)) + + def test_constants(self): + maps = ProcMaps.load(cStringIO.StringIO(self._TEST_PROCMAPS)) + selected = [4, 7] + for index, entry in enumerate(maps.iter(ProcMaps.constants)): + self.assertEqual(entry.as_dict(), + self._expected_as_dict(selected[index])) + + def test_executable(self): + maps = ProcMaps.load(cStringIO.StringIO(self._TEST_PROCMAPS)) + selected = [3, 6] + for index, entry in enumerate(maps.iter(ProcMaps.executable)): + self.assertEqual(entry.as_dict(), + self._expected_as_dict(selected[index])) + + def test_executable_and_constants(self): + maps = ProcMaps.load(cStringIO.StringIO(self._TEST_PROCMAPS)) + selected = [3, 4, 6, 7] + for index, entry in enumerate(maps.iter(ProcMaps.executable_and_constants)): + self.assertEqual(entry.as_dict(), + self._expected_as_dict(selected[index])) + + +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() |