Reworked dbgrbyd.py's --lifetimes so it actually works
Changed so there is no 1-to-1 mk-tag/id assumption, any unique ids create a simulated lifetime to render. This fixes the issue where grows/shrinks left-aligned ids confused dbgrbyd.py. As a plus, now dbgrbyd.py can actually handle multi-id grow/shrinks, and is more robust against out-of-sync grow/shrinks. This sort of lifetime issues are when you'd want to run dgbrbyd.py, so it's a bit important this is handled gracefully.
This commit is contained in:
+116
-64
@@ -189,25 +189,41 @@ def show_log(block_size, data, rev, off, *,
|
|||||||
for x in range(max(chars.keys(), default=0)+1))
|
for x in range(max(chars.keys(), default=0)+1))
|
||||||
|
|
||||||
# preprocess lifetimes
|
# preprocess lifetimes
|
||||||
|
lifetime_width = 0
|
||||||
if args.get('lifetimes'):
|
if args.get('lifetimes'):
|
||||||
|
class Lifetime:
|
||||||
|
color_i = 0
|
||||||
|
def __init__(self, j):
|
||||||
|
self.origin = j
|
||||||
|
self.tags = set()
|
||||||
|
self.color = COLORS[self.__class__.color_i]
|
||||||
|
self.__class__.color_i = (
|
||||||
|
self.__class__.color_i + 1) % len(COLORS)
|
||||||
|
|
||||||
|
def add(self, j):
|
||||||
|
self.tags.add(j)
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self.tags)
|
||||||
|
|
||||||
|
|
||||||
|
# first figure out where each id comes from
|
||||||
|
weights = []
|
||||||
|
lifetimes = []
|
||||||
def index(weights, id):
|
def index(weights, id):
|
||||||
for i, w in enumerate(weights):
|
for i, w in enumerate(weights):
|
||||||
if id < w:
|
if id < w:
|
||||||
return i, id
|
return i, id
|
||||||
id -= w
|
id -= w
|
||||||
return len(weights)-1, -1
|
return len(weights), 0
|
||||||
|
|
||||||
def ranges(weights):
|
checkpoint_js = []
|
||||||
return zip(
|
checkpoints = []
|
||||||
it.chain([0], it.accumulate(weights)),
|
def checkpoint(j, weights, lifetimes, grows, shrinks, tags):
|
||||||
it.accumulate(weights))
|
checkpoint_js.append(j)
|
||||||
|
checkpoints.append((
|
||||||
weights = [0]
|
weights.copy(), lifetimes.copy(),
|
||||||
grow = None
|
grows, shrinks, tags))
|
||||||
colors = ['']
|
|
||||||
colors_i = 0
|
|
||||||
# note these slices are also copying the arrays
|
|
||||||
lifetimes = [(0, 0, -1, weights[:-1], colors[:-1])]
|
|
||||||
|
|
||||||
j_ = 4
|
j_ = 4
|
||||||
while j_ < (block_size if args.get('all') else off):
|
while j_ < (block_size if args.get('all') else off):
|
||||||
@@ -217,68 +233,104 @@ def show_log(block_size, data, rev, off, *,
|
|||||||
if (tag & 0xe) <= 0x4:
|
if (tag & 0xe) <= 0x4:
|
||||||
j_ += size
|
j_ += size
|
||||||
|
|
||||||
if grow is not None:
|
# note we ignore out-of-bounds here for debugging
|
||||||
if ((tag & ~0x3f0) == 0x0400
|
|
||||||
and id >= grow[1]
|
|
||||||
and id < grow[1]+grow[2]):
|
|
||||||
i, p = index(weights, id)
|
|
||||||
weights[i:i+1] = [p+1, weights[i]-(p+1)]
|
|
||||||
colors[i:i+1] = [COLORS[colors_i % len(COLORS)], colors[i]]
|
|
||||||
colors_i += 1
|
|
||||||
lifetimes.append((grow[0],
|
|
||||||
+1, id, weights[:-1], colors[:-1]))
|
|
||||||
grow = None
|
|
||||||
elif not tag & 0x8:
|
|
||||||
lifetimes.append((grow[0],
|
|
||||||
0, grow[1], weights[:-1], colors[:-1]))
|
|
||||||
grow = None
|
|
||||||
|
|
||||||
if tag == 0x0006:
|
if tag == 0x0006:
|
||||||
i, _ = index(weights, id)
|
# grow lifetimes
|
||||||
weights[i] += size
|
i, id_ = index(weights, id)
|
||||||
grow = j, id, size
|
if id_ > 0:
|
||||||
elif tag == 0x0016:
|
weights[i:i+1] = [id_, size, weights[i]-id_]
|
||||||
i, _ = index(weights, id)
|
lifetimes[i:i+1] = [lifetimes[i], Lifetime(j), lifetimes[i]]
|
||||||
if weights[i] == size and len(weights) > 1:
|
|
||||||
lifetimes.append((j,
|
|
||||||
-1, id, weights[:-1], colors[:-1]))
|
|
||||||
weights[i:i+1] = []
|
|
||||||
colors[i:i+1] = []
|
|
||||||
else:
|
else:
|
||||||
weights[i] = max(weights[i] - size, 0)
|
weights[i:i] = [size]
|
||||||
lifetimes.append((j,
|
lifetimes[i:i] = [Lifetime(j)]
|
||||||
0, id-size, weights[:-1], colors[:-1]))
|
|
||||||
elif not tag & 0x8:
|
|
||||||
lifetimes.append((j,
|
|
||||||
0, id, weights[:-1], colors[:-1]))
|
|
||||||
|
|
||||||
lifetimes_j = [j for j, _, _, _, _ in lifetimes]
|
checkpoint(j, weights, lifetimes, {i}, set(), {i})
|
||||||
width = 2*max(len(weights) for _, _, _, weights, _ in lifetimes)
|
|
||||||
|
elif tag == 0x0016:
|
||||||
|
# shrink lifetimes
|
||||||
|
i, id_ = index(weights, id)
|
||||||
|
size_ = size
|
||||||
|
weights_ = weights.copy()
|
||||||
|
lifetimes_ = lifetimes.copy()
|
||||||
|
shrinks = set()
|
||||||
|
while size_ > 0 and i < len(weights_):
|
||||||
|
if id_ > 0:
|
||||||
|
diff = min(size_, weights_[i]-id_)
|
||||||
|
size_ -= diff
|
||||||
|
weights_[i] -= diff
|
||||||
|
i += 1
|
||||||
|
id_ = 0
|
||||||
|
elif weights_[i] > size_:
|
||||||
|
weights_[i] -= size_
|
||||||
|
size_ = 0
|
||||||
|
else:
|
||||||
|
size_ -= weights_[i]
|
||||||
|
weights_[i:i+1] = []
|
||||||
|
lifetimes_[i:i+1] = []
|
||||||
|
shrinks.add(i + len(shrinks))
|
||||||
|
|
||||||
|
checkpoint(j, weights, lifetimes, set(), shrinks, shrinks)
|
||||||
|
weights = weights_
|
||||||
|
lifetimes = lifetimes_
|
||||||
|
|
||||||
|
elif (tag & 0xc) == 0x0:
|
||||||
|
# attach tag to lifetime
|
||||||
|
i, id_ = index(weights, id)
|
||||||
|
if i < len(weights):
|
||||||
|
lifetimes[i].add(j)
|
||||||
|
|
||||||
|
checkpoint(j, weights, lifetimes, set(), set(), {i})
|
||||||
|
|
||||||
|
lifetime_width = 2*max((
|
||||||
|
sum(1 for lifetime in lifetimes if lifetime)
|
||||||
|
for _, lifetimes, _, _, _ in checkpoints),
|
||||||
|
default=0)
|
||||||
|
|
||||||
def lifetimerepr(j):
|
def lifetimerepr(j):
|
||||||
j_, g, id, weights, colors = lifetimes[
|
x = bisect.bisect(checkpoint_js, j)-1
|
||||||
bisect.bisect(lifetimes_j, j)-1]
|
j_ = checkpoint_js[x]
|
||||||
if j != j_:
|
weights, lifetimes, grows, shrinks, tags = checkpoints[x]
|
||||||
g, id = 0, -1
|
|
||||||
|
reprs = []
|
||||||
|
colors = []
|
||||||
|
was = None
|
||||||
|
for i, (w, lifetime) in enumerate(zip(weights, lifetimes)):
|
||||||
|
# skip lifetimes with no tags and shrinks
|
||||||
|
if not lifetime or (j != j_ and i in shrinks):
|
||||||
|
if i in grows or i in shrinks or i in tags:
|
||||||
|
tags = tags.copy()
|
||||||
|
tags.add(i+1)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if j == j_ and i in grows:
|
||||||
|
reprs.append('.')
|
||||||
|
was = 'grow'
|
||||||
|
elif j == j_ and i in shrinks:
|
||||||
|
reprs.append('\'')
|
||||||
|
was = 'shrink'
|
||||||
|
elif j == j_ and i in tags:
|
||||||
|
reprs.append('* ')
|
||||||
|
elif was == 'grow':
|
||||||
|
reprs.append('\\ ')
|
||||||
|
elif was == 'shrink':
|
||||||
|
reprs.append('/ ')
|
||||||
|
else:
|
||||||
|
reprs.append('| ')
|
||||||
|
|
||||||
|
colors.append(lifetime.color)
|
||||||
|
|
||||||
return '%s%*s' % (
|
return '%s%*s' % (
|
||||||
''.join(
|
''.join('%s%s%s' % (
|
||||||
'%s%s%s' % (
|
|
||||||
'\x1b[%sm' % c if color else '',
|
'\x1b[%sm' % c if color else '',
|
||||||
'.' if g > 0 and id >= a and id < b
|
r,
|
||||||
else '\\ ' if g > 0 and id < a
|
|
||||||
else '\'' if g < 0 and id >= a and id < b
|
|
||||||
else '/ ' if g < 0 and id < a
|
|
||||||
else '* ' if id >= a and id < b
|
|
||||||
else '| ',
|
|
||||||
'\x1b[m' if color else '')
|
'\x1b[m' if color else '')
|
||||||
for (a, b), c in zip(ranges(weights), colors)),
|
for r, c in zip(reprs, colors)),
|
||||||
width - 2*len(weights) + (1 if g else 0), '')
|
lifetime_width - sum(len(r) for r in reprs), '')
|
||||||
|
|
||||||
# print header
|
# print header
|
||||||
print('%-8s %s%-22s %s' % (
|
print('%-8s %*s%-22s %s' % (
|
||||||
'off',
|
'off',
|
||||||
lifetimerepr(0) if args.get('lifetimes') else '',
|
lifetime_width, '',
|
||||||
'tag',
|
'tag',
|
||||||
'data (truncated)'
|
'data (truncated)'
|
||||||
if not args.get('no_truncate') else ''))
|
if not args.get('no_truncate') else ''))
|
||||||
@@ -341,10 +393,10 @@ def show_log(block_size, data, rev, off, *,
|
|||||||
# show in-device representation, including some extra
|
# show in-device representation, including some extra
|
||||||
# crc/parity info
|
# crc/parity info
|
||||||
if args.get('device'):
|
if args.get('device'):
|
||||||
print('%s%8s %s%-47s %08x %x%s' % (
|
print('%s%8s %*s%-47s %08x %x%s' % (
|
||||||
'\x1b[90m' if color and j >= off else '',
|
'\x1b[90m' if color and j >= off else '',
|
||||||
'',
|
'',
|
||||||
lifetimerepr(0) if args.get('lifetimes') else '',
|
lifetime_width, '',
|
||||||
'%-22s%s' % (
|
'%-22s%s' % (
|
||||||
'%04x %08x %07x' % (tag, 0xffffffff & id, size),
|
'%04x %08x %07x' % (tag, 0xffffffff & id, size),
|
||||||
' %s' % ' '.join(
|
' %s' % ' '.join(
|
||||||
|
|||||||
Reference in New Issue
Block a user