Viewing: uniqueStacktrace.py
#!/usr/bin/env python
"""
Copyright (c) 2015-2019 Cray Inc. All Rights Reserved.
Utility to print unique stack traces
"""
import re
import sys
import StringIO
import argparse
from pykdump.API import exec_crash_command
description_short = 'Print stack traces for each task.'
# outer loop indentifies PIDs
# inner loop looks for # until
# another PID is found
def sortInput(swapper, input):
ps = re.compile("^PID:\s+(\d+)\s+TASK:\s+([0-9A-Fa-f]+).*")
n = re.compile("^#")
swap = re.compile((".*\"swapper/[0-9]+\""))
info = dict()
PID = ""
STK = ""
tmp = ""
# Outer to check for PIDs
# this loop never breaks;
for line in input:
line = line.strip()
# Inner loop to check for # signs indicating lines we want.
# Having two loops allow for the PID and TSK to be associated
# with a particular trace.
# This loop breaks if a new PID is found (meaning the end of the
# current trace) or if there are no more lines available
while True:
if ps.match(line): break;
line = line.strip()
if n.match(line):
line = line.split()
tmp += " ".join([line[2], line[3], line[4]])
if len(line) == 6 : tmp += " " + line[5]
tmp += '\n\t'
line = input.readline()
if not line: break
if tmp :
if tmp in info:
info[tmp].append((PID,STK))
else:
info[tmp] = [(PID,STK)]
m = ps.match(line)
if m:
PID, STK = m.group(1), m.group(2)
tmp = ""
# if it's swapper line move on
# this prevents entry into inner loop
if not swapper and swap.match(line):
line = input.readline()
sort = sorted(info.items(), key=lambda info: len(info[1]))
return sort
def printRes(sort, printpid, printptr):
"""
Prints out individual stack traces from lowest to highest.
"""
for stack_trace, ptask_list in sort:
if printpid and not printptr:
print("PID: %s" % (', '.join(p[0] for p in ptask_list)))
elif printpid and printptr:
print("PID, TSK: %s" % (', '.join(p[0] + ': ' + p[1] for p in ptask_list)))
elif not printpid and printptr:
print("TSK: %s" % (', '.join(p[1] for p in ptask_list)))
print("TASKS: %d" %(len(ptask_list)))
print("\t%s" %(stack_trace))
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-p", "--print-pid",
action="store_true", dest="printpid", default=False,
help="Print PIDS corresponding to each ST")
parser.add_argument("-q", "--print-taskpntr",
action="store_true", dest="printptr", default=False,
help="Print the task pointers for each ST")
parser.add_argument("-s", "--swapper",
action="store_true", dest="swapper", default=False,
help="Print swapper processes")
parser.add_argument("task_select", metavar="task_selection", nargs="*",
help="task selection argument (passed to foreach cmd)")
args = parser.parse_args()
com = "foreach {ts:s} bt".format(ts=" ".join(args.task_select))
result = exec_crash_command(com)
input = StringIO.StringIO(result)
printRes(sortInput(args.swapper, input), args.printpid, args.printptr)
if __name__ == '__main__':
main()