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

Unified Diff: tools/binary_size/libsupersize/console.py

Issue 2936033002: Supersize diff rewrite + tweaks (Closed)
Patch Set: review comnts Created 3 years, 6 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 | « no previous file | tools/binary_size/libsupersize/describe.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/binary_size/libsupersize/console.py
diff --git a/tools/binary_size/libsupersize/console.py b/tools/binary_size/libsupersize/console.py
index c39396b0ca09fd2211693eb53395a23629dd5ee1..221c55aa637deca35f75fafa26a892c3270fcb5e 100644
--- a/tools/binary_size/libsupersize/console.py
+++ b/tools/binary_size/libsupersize/console.py
@@ -66,7 +66,7 @@ def _WriteToStream(lines, use_pager=None, to_file=None):
class _Session(object):
_readline_initialized = False
- def __init__(self, size_infos, size_paths, lazy_paths):
+ def __init__(self, size_infos, lazy_paths):
self._printed_variables = []
self._variables = {
'Print': self._PrintFunc,
@@ -79,7 +79,6 @@ class _Session(object):
}
self._lazy_paths = lazy_paths
self._size_infos = size_infos
- self._size_paths = size_paths
self._disassemble_prefix_len = None
if len(size_infos) == 1:
@@ -89,7 +88,7 @@ class _Session(object):
self._variables['size_info%d' % (i + 1)] = size_info
def _DiffFunc(self, before=None, after=None, sort=True):
- """Diffs two SizeInfo objects. Returns a SizeInfoDiff.
+ """Diffs two SizeInfo objects. Returns a DeltaSizeInfo.
Args:
before: Defaults to first size_infos[0].
@@ -105,7 +104,7 @@ class _Session(object):
def _PrintFunc(self, obj=None, verbose=False, recursive=False, use_pager=None,
to_file=None):
- """Prints out the given Symbol / SymbolGroup / SymbolDiff / SizeInfo.
+ """Prints out the given Symbol / SymbolGroup / SizeInfo.
For convenience, |obj| will be appended to the global "printed" list.
@@ -127,23 +126,8 @@ class _Session(object):
lines = describe.GenerateLines(obj, verbose=verbose, recursive=recursive)
_WriteToStream(lines, use_pager=use_pager, to_file=to_file)
- def _ElfPathAndToolPrefixForSymbol(self, symbol, elf_path, tool_prefix):
- size_info = None
- size_path = None
- for size_info, size_path in zip(self._size_infos, self._size_paths):
- if symbol in size_info.raw_symbols:
- break
- else:
- # If symbols is from a diff(), use its address+name to find it.
- for size_info, size_path in zip(self._size_infos, self._size_paths):
- matched = size_info.raw_symbols.WhereAddressInRange(symbol.address)
- # Use last matched symbol to skip over padding-only symbols.
- if len(matched) > 0 and matched[-1].full_name == symbol.full_name:
- symbol = matched[-1]
- break
- else:
- assert False, 'Symbol does not belong to a size_info.'
-
+ def _ElfPathAndToolPrefixForSymbol(self, size_info, elf_path):
+ tool_prefix = self._lazy_paths.tool_prefix
orig_tool_prefix = size_info.metadata.get(models.METADATA_TOOL_PREFIX)
if orig_tool_prefix:
orig_tool_prefix = paths.FromSrcRootRelative(orig_tool_prefix)
@@ -156,29 +140,44 @@ class _Session(object):
'Could not determine --tool-prefix. Possible fixes include setting '
'--tool-prefix, or setting --output-directory')
- if elf_path is None:
- filename = size_info.metadata.get(models.METADATA_ELF_FILENAME)
- output_dir = self._lazy_paths.output_directory
- size_path = self._size_paths[self._size_infos.index(size_info)]
- if output_dir:
- # Local build: File is located in output directory.
- path = os.path.normpath(os.path.join(output_dir, filename))
- if not output_dir or not os.path.exists(path):
+ def build_id_matches(elf_path):
+ found_build_id = archive.BuildIdFromElf(elf_path, tool_prefix)
+ expected_build_id = size_info.metadata.get(models.METADATA_ELF_BUILD_ID)
+ return found_build_id == expected_build_id
+
+ filename = size_info.metadata.get(models.METADATA_ELF_FILENAME)
+ paths_to_try = []
+ if elf_path:
+ paths_to_try.append(elf_path)
+ else:
+ auto_lazy_paths = [
+ paths.LazyPaths(any_path_within_output_directory=s.size_path)
+ for s in self._size_infos]
+ for lazy_paths in auto_lazy_paths + [self._lazy_paths]:
+ output_dir = lazy_paths.output_directory
+ if output_dir:
+ # Local build: File is located in output directory.
+ paths_to_try.append(
+ os.path.normpath(os.path.join(output_dir, filename)))
# Downloaded build: File is located beside .size file.
- path = os.path.normpath(os.path.join(
- os.path.dirname(size_path), os.path.basename(filename)))
+ paths_to_try.append(os.path.normpath(os.path.join(
+ os.path.dirname(size_info.size_path), os.path.basename(filename))))
+
+ paths_to_try = [p for p in paths_to_try if os.path.exists(p)]
+
+ for i, elf_path in enumerate(paths_to_try):
+ if build_id_matches(elf_path):
+ return elf_path, tool_prefix
- assert os.path.exists(path), (
- 'Could locate ELF file. If binary was built locally, ensure '
- '--output-directory is set. If output directory is unavailable, '
- 'ensure {} is located beside {}, or pass its path explicitly using '
- 'elf_path=').format(os.path.basename(filename), size_path)
+ # Show an error only once all paths are tried.
+ if i + 1 == len(paths_to_try):
+ assert False, 'Build ID does not match for %s' % elf_path
- found_build_id = archive.BuildIdFromElf(path, tool_prefix)
- expected_build_id = size_info.metadata.get(models.METADATA_ELF_BUILD_ID)
- assert found_build_id == expected_build_id, (
- 'Build ID does not match for %s' % path)
- return path, tool_prefix
+ assert False, (
+ 'Could not locate ELF file. If binary was built locally, ensure '
+ '--output-directory is set. If output directory is unavailable, '
+ 'ensure {} is located beside {}, or pass its path explicitly using '
+ 'elf_path=').format(os.path.basename(filename), size_info.size_path)
def _DetectDisassemblePrefixLen(self, args):
# Look for a line that looks like:
@@ -187,9 +186,16 @@ class _Session(object):
for line in output.splitlines():
if line and line[0] == os.path.sep and line[-1].isdigit():
release_idx = line.find('Release')
- if release_idx == -1:
- break
- return line.count(os.path.sep, 0, release_idx)
+ if release_idx != -1:
+ return line.count(os.path.sep, 0, release_idx)
+ dot_dot_idx = line.find('..')
+ if dot_dot_idx != -1:
+ return line.count(os.path.sep, 0, dot_dot_idx) - 1
+ out_idx = line.find(os.path.sep + 'out')
+ if out_idx != -1:
+ return line.count(os.path.sep, 0, out_idx) + 2
+ logging.warning('Could not guess source path from found path.')
+ return None
logging.warning('Found no source paths in objdump output.')
return None
@@ -204,11 +210,17 @@ class _Session(object):
"""
assert not symbol.IsGroup()
assert symbol.address and symbol.section_name == '.text'
+ assert not symbol.IsDelta(), ('Cannot disasseble a Diff\'ed symbol. Try '
+ 'passing .before_symbol or .after_symbol.')
+ size_info = None
+ for size_info in self._size_infos:
+ if symbol in size_info.raw_symbols:
+ break
+ else:
+ assert False, 'Symbol does not belong to a size_info.'
- tool_prefix = self._lazy_paths.tool_prefix
- if not elf_path:
- elf_path, tool_prefix = self._ElfPathAndToolPrefixForSymbol(
- symbol, elf_path, tool_prefix)
+ elf_path, tool_prefix = self._ElfPathAndToolPrefixForSymbol(
+ size_info, elf_path)
args = [tool_prefix + 'objdump', '--disassemble', '--source',
'--line-numbers', '--demangle',
@@ -278,18 +290,23 @@ class _Session(object):
])
def _CreateBanner(self):
- symbol_info_keys = sorted(m for m in dir(models.SizeInfo) if m[0] != '_')
- symbol_keys = sorted(m for m in dir(models.Symbol) if m[0] != '_')
- symbol_group_keys = [m for m in dir(models.SymbolGroup) if m[0] != '_']
- symbol_diff_keys = sorted(m for m in dir(models.SymbolDiff)
- if m[0] != '_' and m not in symbol_group_keys)
- symbol_group_keys = sorted(m for m in symbol_group_keys
- if m not in symbol_keys)
- canned_queries_keys = sorted(m for m in dir(canned_queries.CannedQueries)
- if m[0] != '_')
+ def keys(cls, super_keys=None):
+ ret = sorted(m for m in dir(cls) if m[0] != '_')
+ if super_keys:
+ ret = sorted(m for m in ret if m not in super_keys)
+ return ret
+
+ symbol_info_keys = keys(models.SizeInfo)
+ symbol_keys = keys(models.Symbol)
+ symbol_group_keys = keys(models.SymbolGroup, symbol_keys)
+ delta_size_info_keys = keys(models.DeltaSizeInfo)
+ delta_symbol_keys = keys(models.DeltaSymbol, symbol_keys)
+ delta_symbol_group_keys = keys(models.DeltaSymbolGroup,
+ symbol_keys + symbol_group_keys)
+ canned_queries_keys = keys(canned_queries.CannedQueries)
+
functions = sorted(k for k in self._variables if k[0].isupper())
- variables = sorted(k for k in self._variables if k[0].islower())
- return '\n'.join([
+ lines = [
'*' * 80,
'Entering interactive Python shell. Quick reference:',
'',
@@ -298,14 +315,23 @@ class _Session(object):
'',
'SymbolGroup (extends Symbol): %s' % ', '.join(symbol_group_keys),
'',
- 'SymbolDiff (extends SymbolGroup): %s' % ', '.join(symbol_diff_keys),
+ 'DeltaSizeInfo: %s' % ', '.join(delta_size_info_keys),
+ 'DeltaSymbol (extends Symbol): %s' % ', '.join(delta_symbol_keys),
+ 'DeltaSymbolGroup (extends SymbolGroup): %s' % ', '.join(
+ delta_symbol_group_keys),
'',
'canned_queries: %s' % ', '.join(canned_queries_keys),
'',
'Functions: %s' % ', '.join('%s()' % f for f in functions),
- 'Variables: %s' % ', '.join(variables),
- '*' * 80,
- ])
+ 'Variables: ',
+ ' printed: List of objects passed to Print().',
+ ]
+ for key, value in self._variables.iteritems():
+ if key.startswith('size_info'):
+ lines.append(' {}: Loaded from {}'.format(key, value.size_path))
+ lines.append('*' * 80)
+ return '\n'.join(lines)
+
@classmethod
def _InitReadline(cls):
@@ -354,7 +380,7 @@ def Run(args, parser):
lazy_paths = paths.LazyPaths(tool_prefix=args.tool_prefix,
output_directory=args.output_directory,
any_path_within_output_directory=args.inputs[0])
- session = _Session(size_infos, args.inputs, lazy_paths)
+ session = _Session(size_infos, lazy_paths)
if args.query:
logging.info('Running query from command-line.')
« no previous file with comments | « no previous file | tools/binary_size/libsupersize/describe.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698