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

Unified Diff: build/android/pylib/symbols/elf_symbolizer.py

Issue 339853004: binary_size_tool: fix for ambiguous addr2line output (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: renamed disambiguation status booleans, rewrote some logic Created 6 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 | build/android/pylib/symbols/elf_symbolizer_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build/android/pylib/symbols/elf_symbolizer.py
diff --git a/build/android/pylib/symbols/elf_symbolizer.py b/build/android/pylib/symbols/elf_symbolizer.py
index b294654f20b1ee3c7f0cdb5c142789f3bc1b5933..f5f1474ef6dbbf54b04560581a89e0f8c898be15 100644
--- a/build/android/pylib/symbols/elf_symbolizer.py
+++ b/build/android/pylib/symbols/elf_symbolizer.py
@@ -75,7 +75,8 @@ class ELFSymbolizer(object):
"""
def __init__(self, elf_file_path, addr2line_path, callback, inlines=False,
- max_concurrent_jobs=None, addr2line_timeout=30, max_queue_size=50):
+ max_concurrent_jobs=None, addr2line_timeout=30, max_queue_size=50,
+ source_root_path=None, strip_base_path=None):
"""Args:
elf_file_path: path of the elf file to be symbolized.
addr2line_path: path of the toolchain's addr2line binary.
@@ -91,6 +92,16 @@ class ELFSymbolizer(object):
max_queue_size: Max number of outstanding requests per addr2line instance.
addr2line_timeout: Max time (in seconds) to wait for a addr2line response.
After the timeout, the instance will be considered hung and respawned.
+ source_root_path: The path to the library source code. Which is used in
Primiano Tucci (use gerrit) 2014/06/25 09:02:58 Nit: s/. Which//
+ the disambiguation process. Disambiguation means to resolve ambiguous
+ source paths, for example turn addr2line output "unicode.cc" into a
+ full and absolute path. In some toolchains only the name of the source
Primiano Tucci (use gerrit) 2014/06/25 09:02:59 Uh, what is the difference between a "full" and a
+ file is output, without any path information; disambiguation searches
+ through the source directory specified by |source_root_path| argument
+ for files whose name matches. If there are multiple files with the
+ same name, disambiguation will fail.
Primiano Tucci (use gerrit) 2014/06/25 09:02:58 Can we reword this a bit and make it a bit more cl
+ strip_base_path: If this base path is found in the beginning of any
Primiano Tucci (use gerrit) 2014/06/25 09:02:58 "rebases the symbols source paths onto |source_roo
+ result, we strip it and replace it with |source_root_path|.
"""
assert(os.path.isfile(addr2line_path)), 'Cannot find ' + addr2line_path
self.elf_file_path = elf_file_path
@@ -104,6 +115,14 @@ class ELFSymbolizer(object):
self.requests_counter = 0 # For generating monotonic request IDs.
self._a2l_instances = [] # Up to |max_concurrent_jobs| _Addr2Line inst.
+ # If necessary, create disambiguation lookup table
+ self.disambiguate = source_root_path is not None
+ self.lookup_table = {}
Primiano Tucci (use gerrit) 2014/06/25 09:02:59 What about: self.disambiguation_table = {} # 'foo
+ self.source_root_path = source_root_path
+ self.strip_base_path = strip_base_path
+ if(self.disambiguate):
+ self._CreateDisambiguationTable()
+
# Create one addr2line instance. More instances will be created on demand
# (up to |max_concurrent_jobs|) depending on the rate of the requests.
self._CreateNewA2LInstance()
@@ -161,6 +180,15 @@ class ELFSymbolizer(object):
self._a2l_instances.append(a2l)
return a2l
+ def _CreateDisambiguationTable(self):
Primiano Tucci (use gerrit) 2014/06/25 09:02:59 Just add a one line comment please: """Non-unique
+ self.lookup_table = {}
+ source_root_path = os.path.abspath(self.source_root_path)
Primiano Tucci (use gerrit) 2014/06/25 09:02:59 I'd do this on line 121 and save one line: self.so
+
+ for root, _, filenames in os.walk(source_root_path):
+ for f in filenames:
+ self.lookup_table[f] = os.path.join(root, f) if (f not in
+ self.lookup_table) else None
+
class Addr2Line(object):
"""A python wrapper around an addr2line instance.
@@ -312,7 +340,22 @@ class ELFSymbolizer(object):
else:
logging.warning('Got invalid symbol path from addr2line: %s' % line2)
- sym_info = ELFSymbolInfo(name, source_path, source_line)
+ # In case disambiguation is on, and needed
+ was_ambiguous = False
+ disambiguated = False
+ if self._symbolizer.disambiguate:
+ if source_path and not source_path.startswith('/'):
Primiano Tucci (use gerrit) 2014/06/25 09:02:58 Probably you can just use: posixpath.isabs(source_
+ source_path = self._symbolizer.lookup_table.get(source_path)
+ was_ambiguous = True
+ disambiguated = source_path is not None
Primiano Tucci (use gerrit) 2014/06/25 09:02:59 Just a doubt: at this point if a2l here returns 'f
+
+ if source_path and self._symbolizer.strip_base_path:
+ # Strip the base path
+ source_path = re.sub('^' + self._symbolizer.strip_base_path,
+ self._symbolizer.source_root_path or '', source_path)
Primiano Tucci (use gerrit) 2014/06/25 09:02:58 Nit: indentation should be 4 spaces here, or inlin
+
+ sym_info = ELFSymbolInfo(name, source_path, source_line, was_ambiguous,
+ disambiguated)
if prev_sym_info:
prev_sym_info.inlined_by = sym_info
if not innermost_sym_info:
@@ -393,14 +436,18 @@ class ELFSymbolizer(object):
class ELFSymbolInfo(object):
"""The result of the symbolization passed as first arg. of each callback."""
- def __init__(self, name, source_path, source_line):
+ def __init__(self, name, source_path, source_line, was_ambiguous=False,
+ disambiguated=False):
"""All the fields here can be None (if addr2line replies with '??')."""
self.name = name
- self.source_path = source_path
+ self.source_path = (None if source_path is None else
Primiano Tucci (use gerrit) 2014/06/25 09:02:58 why do you need this logic (the abs path) here? Di
+ os.path.abspath(source_path))
self.source_line = source_line
# In the case of |inlines|=True, the |inlined_by| points to the outer
# function inlining the current one (and so on, to form a chain).
self.inlined_by = None
+ self.disambiguated = disambiguated
+ self.was_ambiguous = was_ambiguous
def __str__(self):
return '%s [%s:%d]' % (
« no previous file with comments | « no previous file | build/android/pylib/symbols/elf_symbolizer_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698