from __future__ import print_function
import gdb
import mcgdb
from mcgdb.toolbox import my_gdb
[docs]class cmd_CleanFlow(gdb.Command):
def __init__(self):
gdb.Command.__init__ (self, "flow_cleanup", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty):
Event.list_ = [evt for evt in Event.list_ if evt.key and not evt.key.dead]
print ("done")
output = None
DEBUG = False
[docs]class cmd_PrintFlow(gdb.Command):
def __init__(self):
gdb.Command.__init__ (self, "print_flow", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty):
global output
if DEBUG or "+debug" in args:
class printer:
def flush(self):pass
def write(self, data):
print (data,)
output = printer()
else:
if not output or "-debug" in args:
output = open("/home/kevin/.sequenceDebugging.fifo", "w")
if "+clean" in args:
# send a CLEAR request
print ("#!|CLEAN|#", file=output)
# send the entire event list
events = []
events[:] = Event.list_
else:
# just send the last events
events = []
events[:] = Event.lasts_
# forget about "last events
Event.lasts_[:] = []
for evt in events:
print (str(evt), file=output)
print ("#!|DONE|#", file=output)
output.flush()
print_flow = None
[docs]class cmd_PrintOrg(gdb.Command):
def __init__(self):
gdb.Command.__init__ (self, "print_org", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty):
FILENAME = "sequenceDebugging"
print_all = False
print_active = False
only_bufferids = []
only_kernelids = []
rest = str(args)
while rest != "":
first, part, rest = rest.partition(" ")
if first == "+all":
print_all = True
if first == "+active":
print_active = True
elif first.startswith("+k=") or first.startswith("+b="):
target = only_bufferids if first[1] == "b" else only_kernelids
try:
target.append(int(first[3:]))
except ValueError:
my_gdb.log.warning("argument '%s' invalid, expected an integer after =", first)
else:
my_gdb.log.warning("argument '%s' not recognized", first)
def do_filter(listz, clazz):
only = []
for item in clazz.list_:
if item.numbers[clazz] in listz:
only.append(item)
return only
only_buffers = do_filter(only_bufferids, Buffer)
only_kernels = do_filter(only_kernelids, Kernel)
with open("%s.dot" % FILENAME, "w") as output:
print ("digraph G { rankdir=LR;", file=output)
for cname, cid in [("Context 1", "ctx1")]:
cuid = "context_%s" % cid
print ("subgraph cluster_%s {" % cuid, file=output)
print (' label="%s" ' % cname, file=output)
for buffer in Buffer.list_:
if not print_all and buffer.never_used:
continue
if only_buffers and not(buffer in only_buffers):
continue
if only_kernels and not(sum([kern.count_buffer_use(buffer) for kern in only_kernels])):
continue
if print_active and not buffer.in_use:
continue
bnum = buffer.numbers[Buffer]
buid = "buffer_%s" % bnum
if buffer.mode == Buffer.READ_ONLY:
color = {Buffer.WRITE_AVAILABLE: "green",
Buffer.READ_AVAILABLE: "orange"}[buffer.state]
else:
color = {Buffer.WRITE_AVAILABLE: "green",
Buffer.TRANSFERED: "turquoise",
Buffer.READ_AVAILABLE: "blue"}[buffer.state]
print ('%s [label="Buffer #%d (%s)"] [style = filled color = %s]' % (buid, bnum, buffer.mode[1], color), file=output)
#print kernels, program per program
for program in Program.list_:
puid = "program_%s" % program.uid
print ("subgraph cluster_%s {" % puid, file=output)
print (' label= "%s"' % program.name, file=output)
for kernel in program.kernels:
if not print_all and not(kernel.buffers or kernel.buffers_hist):
continue
if only_kernels and not(kernel in only_kernels):
continue
if only_buffers and not(sum([buff.count_kernel_use(kernel) for buff in only_buffers])):
continue
if print_active and not(kernel.buffers):
continue
knum = kernel.numbers[Kernel]
kuid = "kernel_%s" % knum
print ('%s [label="Kernel #%d %s"] [shape=rect color=yellow]' % (kuid, knum, kernel.name,))
print ("}", file=output)
print ("}", file=output)
max_cnt = max([max(kern.buffers_hist.values()+[0]) for kern in Kernel.list_])
MAX_PENWIDTH = 5
# print connections
for kernel in Kernel.list_:
if only_kernels and not(kernel in only_kernels):
continue
knum = kernel.numbers[Kernel]
kuid = "kernel_%s" % knum
for buffer in kernel.buffers:
bnum = buffer.numbers[Buffer]
if only_buffers and not(bnum in only_buffers):
continue
buid = "buffer_%s" % bnum
print ('%s -> %s [color=red]' % (buid, kuid), file=output)
if print_active:
continue
for buffer, cnt in kernel.buffers_hist.items():
if cnt == 0:
continue
if only_buffers and not(buffer in only_buffers):
continue
bnum = buffer.numbers[Buffer]
buid = "buffer_%s" % bnum
cnt_ratio = float(cnt)/max_cnt*MAX_PENWIDTH
print ('%s -> %s [color=green penwidth=%d dir="%s"]' % (buid, kuid, cnt_ratio, buffer.get_buffer_kernel_direction()), file=output)
print ("}%", file=output)
os.system("dot -Tpng %(name)s.dot -o %(name)s.png" % {"name":FILENAME})
print (FILENAME+".png")
autograph = None
[docs]def erase_common_prefix(old, new_):
edit_str = list(new_)
if not old:
return new_, new_
common = 0
try:
for i in range(len(old)):
if old[i] == new_[i] and new_[i] != '_':
edit_str[i] = '.'
common += 1
else:
break
except:
pass
try:
new_end = len(new_)
old_end = len(new_)
for i in len(old) - 1:
if old[old_end - i] == new_[new_end - i] and new_[new_end - i] != '_':
edit_str[new_end - i] = '.'
common += 1
else:
break
except:
pass
if common > 3:
return old, "".join(edit_str)
else:
return new_, "".join(edit_str)
[docs]class cmd_InfoPrograms(gdb.Command):
"""info programs"""
def __init__(self):
gdb.Command.__init__ (self, "info programs", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty):
selected = []
do_kernels = False
kernel_args = ""
for arg in str(args).split(" "):
if arg.isdigit():
selected.append(int(arg))
elif arg == "+kernels" or arg.startswith("+kernels="):
do_kernels = True
if arg.startswith("+kernels="):
kernel_args += " "+arg[len("+kernels="):]
for prg in Program.list_:
number = prg.numbers[Program]
if len(selected) != 0 and number not in selected:
continue
print ("#%d %s" % (number, prg))
if do_kernels and prg.kernels:
print ("\t"+gdb.execute("info kernels -complain %s %s" % (kernel_args, " ".join([str(ker.numbers[Kernel]) for ker in prg.kernels])), to_string=True).replace("\n", "\n\t"))
[docs]class cmd_InfoKernels(gdb.Command):
"""info kernels [+where] [{?+-}break +use_count] [{?+-}hide] [-unused]"""
def __init__(self):
gdb.Command.__init__ (self, "info kernels", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty):
selected = []
do_where = False
do_use_count = False
do_show_break = False
do_program = False
set_break = None
only_used = False
do_hide = False
do_handle = False
handle_args = []
name_args = []
set_hide = None
do_complain = True
for arg in str(args).split(" "):
if arg.isdigit():
selected.append(int(arg))
elif arg == "+where":
do_where = True
elif arg == "+use_count":
do_use_count = True
elif arg == "-unused":
only_used = True
elif arg == "?break":
do_show_break = True
elif arg == "+break":
do_show_break = True
set_break = True
elif arg == "-break":
do_show_break = True
set_break = False
elif arg == "?hide":
do_hide = True
elif arg == "-hide":
set_hide = False
elif arg == "+hide":
set_hide = True
elif arg == "+program":
do_program = True
elif arg.startswith("+name="):
name_args.append(arg[len("+name="):])
elif arg == "+handle" or arg.startswith("+handle="):
do_handle = True
if arg.startswith("+handle="):
handle_args.append(arg[len("+handle="):])
elif arg == "-complain":
do_complain = False
elif arg == "":
pass
elif do_complain:
print ("Argument '%s' not recognized" % arg)
prev_name = None
for ker in Kernel.list_:
number = ker.numbers[Kernel]
if len(selected) != 0 and number not in selected:
continue
if (len(selected) == 0 and ker.hide) and not (set_hide is False):
continue
if only_used and ker.use_count == 0:
continue
if handle_args and not ker.uid in handle_args:
continue
if name_args and not [prf for prf in name_args if ker.name.startswith(prf)]:
continue
prev_name, name = erase_common_prefix(prev_name, ker.name)
print ("#%d %s" % (number, name))
if do_where:
print ("\t"+ker.stack.replace("\n", "\n\t"))
if do_use_count:
print ("\tUse count: %d" % ker.use_count)
if do_handle:
print ("\tHandle: %s" % ker.uid)
if do_show_break:
if set_break is not None:
ker.do_break = set_break
print ("\tBreak: %s" % ker.do_break)
if do_hide:
print ("\tHide: %s" % ker.hide)
if set_hide is not None:
ker.hide = set_hide
if do_program:
print ("\tProgram: %s" % ker.program)
[docs]class cmd_InfoBuffers(gdb.Command):
def __init__(self):
gdb.Command.__init__ (self, "info buffers", gdb.COMMAND_NONE)
[docs] def invoke (self, args, from_tty):
selected = []
do_where = False
do_line = False
do_use_count = False
do_show_break = False
set_break = None
only_used = False
do_handle = False
handle_args = []
show_dead = False
for arg in str(args).split(" "):
if arg.isdigit():
selected.append(int(arg))
elif arg == "+line":
do_line = True
elif arg == "+where":
do_line = True
do_where = True
elif arg == "+use_count":
do_use_count = True
elif arg == "-unused":
only_used = True
elif arg == "+dead":
show_dead = True
elif arg == "+handle" or arg.startswith("+handle="):
do_handle = True
if arg.startswith("+handle="):
handle_args.append(arg[len("+handle="):])
elif arg == "?break":
do_show_break = True
elif arg == "+break":
do_show_break = True
set_break = True
elif arg == "-break":
do_show_break = True
set_break = False
else:
print ("Argument '%s' not recognized" % arg)
for buf in Buffer.list_:
number = buf.numbers[Buffer]
if buf.dead and not show_dead:
continue
if len(selected) != 0 and number not in selected:
continue
if only_used and buf.use_count == 0:
continue
if handle_args and not buf.uid in handle_args:
continue
line = buf.get_name() +" "+ buf.state
if buf.dead: line = "(%s)" % line
print (line)
if do_line:
print ("> "+buf.line)
if do_where:
print ("\t"+buf.stack.replace("\n", "\n\t"))
if do_use_count:
print ("\tUse count: %d" % buf.use_count)
if do_handle:
print ("\tHandle: %s" % buf.uid)
if do_show_break:
if set_break is not None:
buf.do_break = set_break
print ("\tBreak: %s" % buf.do_break)
[docs]def activate():
cmd_PrintFlow()
global print_flow
print_flow = cmd_PrintFlow()
cmd_PrintOrg()
global autograph
autograph = gdb.Parameter("autograph", gdb.COMMAND_NONE, gdb.PARAM_BOOLEAN)
cmd_InfoPrograms()
cmd_InfoKernels()
cmd_InfoBuffers()