forked from Imagelibrary/littlefs
scripts: Added Line class for collect_dwarf_lines
It seems like a good rule of thumb is for every XInfo class to be paired with at least a small X class wrapper: - Easier to extend without breaking tuple unpacking everywhere - Better code readability - Better memory reuse in _by_addr caches (less tuple repacking)
This commit is contained in:
@@ -397,6 +397,18 @@ def collect_syms(obj_path, global_=False, sections=None, *,
|
|||||||
|
|
||||||
return SymInfo(syms)
|
return SymInfo(syms)
|
||||||
|
|
||||||
|
class Line(co.namedtuple('Line', ['file', 'line', 'addr'])):
|
||||||
|
__slots__ = ()
|
||||||
|
def __new__(cls, file, line, addr):
|
||||||
|
return super().__new__(cls, file, line, addr)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '%s(%r, %r, 0x%x)' % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.file,
|
||||||
|
self.line,
|
||||||
|
self.addr)
|
||||||
|
|
||||||
class LineInfo:
|
class LineInfo:
|
||||||
def __init__(self, lines):
|
def __init__(self, lines):
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
@@ -410,20 +422,20 @@ class LineInfo:
|
|||||||
if not hasattr(self, '_by_addr'):
|
if not hasattr(self, '_by_addr'):
|
||||||
# sort and keep first when duplicates
|
# sort and keep first when duplicates
|
||||||
lines = self.lines.copy()
|
lines = self.lines.copy()
|
||||||
lines.sort(key=lambda x: (x[2], x[0], x[1]))
|
lines.sort(key=lambda x: (x.addr, x.file, x.line))
|
||||||
|
|
||||||
by_addr = []
|
by_addr = []
|
||||||
for file, line, addr in lines:
|
for line in lines:
|
||||||
if (len(by_addr) == 0
|
if (len(by_addr) == 0
|
||||||
or by_addr[-1][2] != addr):
|
or by_addr[-1].addr != line.addr):
|
||||||
by_addr.append((file, line, addr))
|
by_addr.append(line)
|
||||||
self._by_addr = by_addr
|
self._by_addr = by_addr
|
||||||
|
|
||||||
# find file+line by addr
|
# find file+line by addr
|
||||||
i = bisect.bisect(self._by_addr, k,
|
i = bisect.bisect(self._by_addr, k,
|
||||||
key=lambda x: x[2])
|
key=lambda x: x.addr)
|
||||||
if i > 0:
|
if i > 0:
|
||||||
return self._by_addr[i-1][0], self._by_addr[i-1][1]
|
return self._by_addr[i-1]
|
||||||
else:
|
else:
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@@ -437,19 +449,19 @@ class LineInfo:
|
|||||||
lines.sort()
|
lines.sort()
|
||||||
|
|
||||||
by_line = []
|
by_line = []
|
||||||
for file, line, addr in lines:
|
for line in lines:
|
||||||
if (len(by_line) == 0
|
if (len(by_line) == 0
|
||||||
or by_line[-1][0] != file
|
or by_line[-1].file != line.file
|
||||||
or by_line[-1][1] != line):
|
or by_line[-1].line != line.line):
|
||||||
by_line.append((file, line, addr))
|
by_line.append(line)
|
||||||
self._by_line = by_line
|
self._by_line = by_line
|
||||||
|
|
||||||
# find addr by file+line tuple
|
# find addr by file+line tuple
|
||||||
i = bisect.bisect(self._by_line, k,
|
i = bisect.bisect(self._by_line, k,
|
||||||
key=lambda x: (x[0], x[1]))
|
key=lambda x: (x.file, x.line))
|
||||||
# make sure file at least matches!
|
# make sure file at least matches!
|
||||||
if i > 0 and self._by_line[i-1][0] == k[0]:
|
if i > 0 and self._by_line[i-1].file == k[0]:
|
||||||
return self._by_line[i-1][2]
|
return self._by_line[i-1]
|
||||||
else:
|
else:
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@@ -534,7 +546,7 @@ def collect_dwarf_lines(obj_path, *,
|
|||||||
or m.group('op_copy')
|
or m.group('op_copy')
|
||||||
or m.group('op_end')):
|
or m.group('op_end')):
|
||||||
file = os.path.abspath(files.get(op_file, '?'))
|
file = os.path.abspath(files.get(op_file, '?'))
|
||||||
lines.append((file, op_line, op_addr))
|
lines.append(Line(file, op_line, op_addr))
|
||||||
|
|
||||||
if m.group('op_end'):
|
if m.group('op_end'):
|
||||||
op_file = 1
|
op_file = 1
|
||||||
@@ -686,7 +698,7 @@ def collect_decompressed(path, *,
|
|||||||
# find file+line
|
# find file+line
|
||||||
line_ = lines.get(addr)
|
line_ = lines.get(addr)
|
||||||
if line_ is not None:
|
if line_ is not None:
|
||||||
file, line = line_
|
file, line = line_.file, line_.line
|
||||||
else:
|
else:
|
||||||
file, line = re.sub('(\.o)?$', '.c', dso, 1), 0
|
file, line = re.sub('(\.o)?$', '.c', dso, 1), 0
|
||||||
|
|
||||||
|
|||||||
@@ -303,6 +303,18 @@ def collect_syms(obj_path, global_=False, sections=None, *,
|
|||||||
|
|
||||||
return SymInfo(syms)
|
return SymInfo(syms)
|
||||||
|
|
||||||
|
class Line(co.namedtuple('Line', ['file', 'line', 'addr'])):
|
||||||
|
__slots__ = ()
|
||||||
|
def __new__(cls, file, line, addr):
|
||||||
|
return super().__new__(cls, file, line, addr)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return '%s(%r, %r, 0x%x)' % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
self.file,
|
||||||
|
self.line,
|
||||||
|
self.addr)
|
||||||
|
|
||||||
class LineInfo:
|
class LineInfo:
|
||||||
def __init__(self, lines):
|
def __init__(self, lines):
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
@@ -316,20 +328,20 @@ class LineInfo:
|
|||||||
if not hasattr(self, '_by_addr'):
|
if not hasattr(self, '_by_addr'):
|
||||||
# sort and keep first when duplicates
|
# sort and keep first when duplicates
|
||||||
lines = self.lines.copy()
|
lines = self.lines.copy()
|
||||||
lines.sort(key=lambda x: (x[2], x[0], x[1]))
|
lines.sort(key=lambda x: (x.addr, x.file, x.line))
|
||||||
|
|
||||||
by_addr = []
|
by_addr = []
|
||||||
for file, line, addr in lines:
|
for line in lines:
|
||||||
if (len(by_addr) == 0
|
if (len(by_addr) == 0
|
||||||
or by_addr[-1][2] != addr):
|
or by_addr[-1].addr != line.addr):
|
||||||
by_addr.append((file, line, addr))
|
by_addr.append(line)
|
||||||
self._by_addr = by_addr
|
self._by_addr = by_addr
|
||||||
|
|
||||||
# find file+line by addr
|
# find file+line by addr
|
||||||
i = bisect.bisect(self._by_addr, k,
|
i = bisect.bisect(self._by_addr, k,
|
||||||
key=lambda x: x[2])
|
key=lambda x: x.addr)
|
||||||
if i > 0:
|
if i > 0:
|
||||||
return self._by_addr[i-1][0], self._by_addr[i-1][1]
|
return self._by_addr[i-1]
|
||||||
else:
|
else:
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@@ -343,19 +355,19 @@ class LineInfo:
|
|||||||
lines.sort()
|
lines.sort()
|
||||||
|
|
||||||
by_line = []
|
by_line = []
|
||||||
for file, line, addr in lines:
|
for line in lines:
|
||||||
if (len(by_line) == 0
|
if (len(by_line) == 0
|
||||||
or by_line[-1][0] != file
|
or by_line[-1].file != line.file
|
||||||
or by_line[-1][1] != line):
|
or by_line[-1].line != line.line):
|
||||||
by_line.append((file, line, addr))
|
by_line.append(line)
|
||||||
self._by_line = by_line
|
self._by_line = by_line
|
||||||
|
|
||||||
# find addr by file+line tuple
|
# find addr by file+line tuple
|
||||||
i = bisect.bisect(self._by_line, k,
|
i = bisect.bisect(self._by_line, k,
|
||||||
key=lambda x: (x[0], x[1]))
|
key=lambda x: (x.file, x.line))
|
||||||
# make sure file at least matches!
|
# make sure file at least matches!
|
||||||
if i > 0 and self._by_line[i-1][0] == k[0]:
|
if i > 0 and self._by_line[i-1].file == k[0]:
|
||||||
return self._by_line[i-1][2]
|
return self._by_line[i-1]
|
||||||
else:
|
else:
|
||||||
return d
|
return d
|
||||||
|
|
||||||
@@ -439,7 +451,7 @@ def collect_dwarf_lines(obj_path, *,
|
|||||||
or m.group('op_copy')
|
or m.group('op_copy')
|
||||||
or m.group('op_end')):
|
or m.group('op_end')):
|
||||||
file = os.path.abspath(files.get(op_file, '?'))
|
file = os.path.abspath(files.get(op_file, '?'))
|
||||||
lines.append((file, op_line, op_addr))
|
lines.append(Line(file, op_line, op_addr))
|
||||||
|
|
||||||
if m.group('op_end'):
|
if m.group('op_end'):
|
||||||
op_file = 1
|
op_file = 1
|
||||||
@@ -606,9 +618,9 @@ def collect_job(path, start, stop, syms, lines, *,
|
|||||||
# the first stack frame, so we can use that as a point
|
# the first stack frame, so we can use that as a point
|
||||||
# of reference
|
# of reference
|
||||||
if last_delta is None:
|
if last_delta is None:
|
||||||
addr__ = lines.get((last_file, last_line))
|
line_ = lines.get((last_file, last_line))
|
||||||
if addr__ is not None:
|
if line_ is not None:
|
||||||
last_delta = addr__ - addr_
|
last_delta = line_.addr - addr_
|
||||||
else:
|
else:
|
||||||
# can't reverse ASLR, give up on backtrace
|
# can't reverse ASLR, give up on backtrace
|
||||||
commit()
|
commit()
|
||||||
@@ -644,7 +656,7 @@ def collect_job(path, start, stop, syms, lines, *,
|
|||||||
# find file+line
|
# find file+line
|
||||||
line_ = lines.get(addr)
|
line_ = lines.get(addr)
|
||||||
if line_ is not None:
|
if line_ is not None:
|
||||||
file, line = line_
|
file, line = line_.file, line_.line
|
||||||
elif len(last_stack) == 0:
|
elif len(last_stack) == 0:
|
||||||
file, line = last_file, last_line
|
file, line = last_file, last_line
|
||||||
else:
|
else:
|
||||||
|
|||||||
Reference in New Issue
Block a user