Skip to content
Snippets Groups Projects

Add new argument to info fibres to enable grouping by line/stack

Merged Mohammed Bilal Akhtar requested to merge mbakhtar/KOS:fibre-grouping-initial into master
@@ -145,30 +145,113 @@ class FibreSupport():
@@ -145,30 +145,113 @@ class FibreSupport():
class InfoFibres(gdb.Command):
class InfoFibres(gdb.Command):
"""Print list of fibres"""
"""Print list of fibres"""
 
header = " Idx \tTarget\tPtr \t\t Frame"
 
def __init__(self):
def __init__(self):
super(InfoFibres, self).__init__("info fibres", gdb.COMMAND_USER)
super(InfoFibres, self).__init__("info fibres", gdb.COMMAND_USER)
def invoke(self, arg, from_tty):
def get_frame_string(self, frame):
curr = gdb.parse_and_eval("Context::currStack")
# Print instruction pointer
print(" Idx \tTarget\tPtr \t\t Frame")
result = str(frame.read_register('rip')).split(None, 1)[0]
 
result += " in " + frame.name()
 
sal = frame.find_sal()
 
if sal is not None and sal.symtab is not None:
 
result += " at " + sal.symtab.filename + ":" + str(sal.line)
 
return result
 
 
def get_row_for(self, idx, curr, frame, print_frame_info=True):
 
result = ""
 
if (str(FibreSupport.list[idx]) == curr):
 
result += "* "
 
else:
 
result += " "
 
result += str(idx) + "\tFibre\t" + str(FibreSupport.list[idx])
 
 
if frame is not None and print_frame_info == True:
 
result += '\t' + self.get_frame_string(frame)
 
return result
 
 
def print_all_fibres(self, curr):
 
print(self.header)
 
for i in range(len(FibreSupport.list)):
 
with FibreSupport.get_frame(FibreSupport.list[i]) as frame:
 
print(self.get_row_for(i, curr, frame))
 
 
def print_grouped_fibres(self, curr, n):
 
all_fibres = FibreSupport.list
 
groups = {}
 
all_output = []
for i in range(len(FibreSupport.list)):
for i in range(len(FibreSupport.list)):
if (FibreSupport.list[i] == curr):
print("* ", end='')
else:
print(" ", end='')
print(str(i), "\tFibre\t", str(FibreSupport.list[i]), sep='', end='')
with FibreSupport.get_frame(FibreSupport.list[i]) as frame:
with FibreSupport.get_frame(FibreSupport.list[i]) as frame:
if frame is not None:
all_output.append((
# Print instruction pointer
self.get_row_for(i, curr, frame, False),
print("\t", str(gdb.parse_and_eval("$rip")).split(None, 1)[0], end='')
self.get_frame_string(frame),
print(" in ", frame.name(), sep='', end='')
))
sal = frame.find_sal()
if frame is None:
if sal is not None and sal.symtab is not None:
continue
print(" at ", sal.symtab.filename, ":", sal.line, sep='')
else:
# Find stack similarities (up to n frames)
print()
newframe = frame
 
prevframe = None
 
rip_str = ""
 
for j in range(n+1):
 
rip_str += str(newframe.read_register('rip')).split(None, 1)[0] + ","
 
# Step one frame up ("older" in gdb's vernacular)
 
try:
 
prevframe = newframe
 
newframe = newframe.older()
 
if newframe == None:
 
break
 
except:
 
break
 
elem = (i, prevframe.name())
 
if rip_str in groups:
 
groups[rip_str].append(elem)
 
else:
 
groups[rip_str] = [elem]
 
 
grouped_indices = set()
 
sorted_groups = list(groups.items())
 
sorted(sorted_groups, key=lambda x: len(x[1])) # Smaller groups first
 
for rip, fibres in sorted_groups:
 
if len(fibres) <= 1:
 
# Skip groups of 1
 
continue
 
print("Fibres called by same line in ", fibres[0][1], " :")
 
indices = map(lambda x: x[0], fibres)
 
joined_indices = []
 
for i in indices:
 
grouped_indices.add(i)
 
if len(joined_indices) > 0 and (joined_indices[-1][1] + 1) == i:
 
start, end = joined_indices[-1]
 
joined_indices[-1] = (start, i)
else:
else:
print()
joined_indices.append((i,i))
 
joined_indices_strs = map(
 
lambda x: '%d-%d' % (x[0], x[1]) if x[0] < x[1] else str(x[0]),
 
joined_indices
 
)
 
print(', '.join(list(joined_indices_strs)))
 
print() # Extra newline
 
 
# Print anything not grouped
 
ungrouped = set(range(len(all_output))) - grouped_indices
 
if len(ungrouped) > 0:
 
print('All ungrouped fibres')
 
print(self.header)
 
for i in ungrouped:
 
fibre_info, frame_info = all_output[i]
 
print(fibre_info, '\t', frame_info)
 
 
def invoke(self, arg, from_tty):
 
curr = str(gdb.parse_and_eval("Context::currStack"))
 
try:
 
if (arg != None and int(arg) >= 0):
 
self.print_grouped_fibres(curr, int(arg))
 
else:
 
self.print_all_fibres(curr)
 
except ValueError:
 
self.print_all_fibres(curr)
class Fibre(gdb.Command):
class Fibre(gdb.Command):
def __init__(self):
def __init__(self):
Loading