Skip to content

Commit aaf6d3b

Browse files
authored
DLPX-90487 sdb stacks appears to loop resulting in many repeated stack frames (#349)
PR URL: https://www.github.com/delphix/sdb/pull/349
1 parent 26d2d54 commit aaf6d3b

File tree

1 file changed

+40
-3
lines changed

1 file changed

+40
-3
lines changed

sdb/commands/linux/stacks.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,12 @@ def aggregate_stacks(
369369
stack_aggr[stack_key].append(task)
370370
return sorted(stack_aggr.items(), key=lambda x: len(x[1]), reverse=True)
371371

372+
@staticmethod
373+
def frame_string(frame_info: str, count: int) -> str:
374+
if count > 1:
375+
return f"{frame_info} ({str(count)})\n"
376+
return f"{frame_info}\n"
377+
372378
def print_stacks(self, objs: Iterable[drgn.Object]) -> None:
373379
self.print_header()
374380
for stack_key, tasks in KernelStacks.aggregate_stacks(objs):
@@ -382,16 +388,47 @@ def print_stacks(self, objs: Iterable[drgn.Object]) -> None:
382388
task_ptr = hex(tasks[0].value_())
383389
stacktrace_info += f"{task_ptr:<18s} {task_state:<16s} {len(tasks):6d}\n"
384390

391+
#
392+
# List the frames for each task in the stack. Ignore frames
393+
# with a program counter of zero (sometimes the stack will be
394+
# padded out with zeros). Aggregate frames with the same program
395+
# counter and offset.
396+
#
385397
frame_pcs: Tuple[int, ...] = stack_key[1]
398+
last_frame_pc = 0x0
399+
last_offset = 0x0
400+
count = 0
386401
for frame_pc in frame_pcs:
387402
try:
403+
# ignore frames with a program counter of zero
404+
if frame_pc == 0x0:
405+
continue
388406
sym = sdb.get_symbol(frame_pc)
389407
func = sym.name
390408
offset = frame_pc - sym.address
409+
if frame_pc == last_frame_pc and offset == last_offset:
410+
count += 1
411+
continue
412+
# emit the last frame we have accumulated
413+
if count > 0:
414+
stacktrace_info += KernelStacks.frame_string(frame_info, count)
415+
frame_info = f"{'':18s}{func}+0x{hex(offset)}"
416+
last_frame_pc = frame_pc
417+
last_offset = offset
418+
count = 1
391419
except LookupError:
392-
func = hex(frame_pc)
393-
offset = 0x0
394-
stacktrace_info += f"{'':18s}{func}+{hex(offset)}\n"
420+
if frame_pc == last_frame_pc:
421+
count += 1
422+
continue
423+
# emit any previous frame info we have accumulated
424+
if count > 0:
425+
stacktrace_info += KernelStacks.frame_string(frame_info, count)
426+
frame_info = f"{'':18s}{hex(frame_pc)}+0x0"
427+
last_frame_pc = frame_pc
428+
count = 1
429+
# emit the final frame if we have one
430+
if count > 0:
431+
stacktrace_info += KernelStacks.frame_string(frame_info, count)
395432
print(stacktrace_info)
396433

397434
def pretty_print(self, objs: Iterable[drgn.Object]) -> None:

0 commit comments

Comments
 (0)