--- /dev/null
+import gdb
+import gdb.types
+import matplotlib.pyplot as plt
+
+import sys, traceback
+
+
+class PlotterCommand(gdb.Command):
+ """Plot arrays"""
+ def __init__(self):
+ super(PlotterCommand, self).__init__("plot", gdb.COMMAND_DATA, gdb.COMPLETE_SYMBOL)
+
+
+ def invoke(self, arg, from_tty):
+ args = gdb.string_to_argv(arg)
+ v = gdb.parse_and_eval(args[0])
+
+ # check value is array or pointer
+ t = v.type.strip_typedefs()
+ if t.code != gdb.TYPE_CODE_ARRAY and t.code != gdb.TYPE_CODE_PTR:
+ raise TypeError("Only arrays and pointers are supported")
+
+ # find array size
+ if len(args) > 1:
+ n = int(args[1]) # user defined size
+ else:
+ if v.type.code == gdb.TYPE_CODE_ARRAY:
+ n = v.type.sizeof / v.type.target().sizeof # arraysize
+ else:
+ raise gdb.error("array size must be specified for pointers")
+
+
+ try:
+ l = [float(v[i]) for i in range(n)]
+ plt.plot(l)
+ plt.show()
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ traceback.print_exception(exc_type, exc_value, exc_traceback)
+
+
+PlotterCommand()
+
+
member_pointers = find_outgoing_pointers(value[f.name])
merge_dict(result, member_pointers)
elif type_is_pointer(f.type):
- result[f.name] = value[f.name]
+ result["->"+f.name] = value[f.name]
elif type_is_reference(f.type):
- result[f.name] = value[f.name].referenced_value().address
+ result["."+f.name] = value[f.name].referenced_value().address
return result
else:
# draw node name
name_layout = context.create_layout()
name_layout.set_font_description(pango.FontDescription("sans 8"))
- display_name = str(node.gdb_value.address) #node.name
- #display_name = node.name
+ #display_name = str(node.gdb_value.address)
+ display_name = node.name
if node is not self.selected_node:
template_args_start = display_name.find("<")
if template_args_start != -1:
name_layout = context.create_layout()
name_layout.set_font_description(pango.FontDescription("sans 8"))
name_layout.set_text(u"\u2192"+name)
+ #name_layout.set_text(name)
_, name_height = name_layout.get_pixel_size()
rotation = -orientation(vx, vy)
y_offset = -name_height - 2 # a couple of extra pixels to avoid text "stepping on the line"
def on_entry_changed(self, entry):
expression = entry.get_text()
value = gdb.parse_and_eval(expression)
- nodes = create_viewer_nodes(value, self.recursion_level)
+ nodes = create_viewer_nodes(expression, value, self.recursion_level)
self.viewer.nodes = nodes
self.viewer.queue_draw()
-def visit_values(node_dict, value, x, y, recursion_level):
+def visit_values(node_dict, node_name, value, x, y, recursion_level):
"""
Recursively traverse children of a gdb Value, storing pairs (address_as_uint, GraphViewerNode).
returns (width, height, node_dict)
return NODE_SPACING, NODE_SPACING
# check if node has already been visited, don't create repeated nodes
- node_dict[address_to_uint(value.address)] = GraphViewerNode(x, y, str(value.type), value)
+ node_dict[address_to_uint(value.address)] = GraphViewerNode(x, y, node_name, value)
width = NODE_SPACING
height = 0
children_x = x+NODE_SPACING
children_height = 0
children = find_outgoing_pointers(value)
- print "value =",value
- children2 = {}
- for k in children:
- children2[k] = str(children[k])
- print "children =",children2
for (child_name, child_value) in children.iteritems():
# compute child "tree" dimensions (layout is always tree-like even if there are edges that make this a generic graph)
+ if child_name == '*':
+ child_node_name = "(*%s)"%node_name
+ else:
+ child_node_name = node_name + child_name
if child_value != 0:
- child_width, child_height = visit_values(node_dict, child_value.referenced_value(), children_x, children_y, recursion_level - 1)
+ child_width, child_height = visit_values(node_dict, child_node_name, child_value.referenced_value(), children_x, children_y, recursion_level - 1)
children_y += child_height
children_height += child_height
width = max(width, NODE_SPACING + child_width)
print "unknown type:", value.type
-def create_viewer_nodes(value, recursion_level):
+def create_viewer_nodes(expr, value, recursion_level):
# create the nodes
nodes = {}
- width, height = visit_values(nodes, value, 50, 50, recursion_level)
+ width, height = visit_values(nodes, expr, value, 50, 50, recursion_level)
# establish connections between nodes when all the nodes are there
for addr in nodes:
window.recursion_level = recursion_level
window.show_all()
- nodes = create_viewer_nodes(value, recursion_level)
+ nodes = create_viewer_nodes(args[0], value, recursion_level)
window.viewer.nodes = nodes
window.viewer.queue_draw()
is_gtk_main_running = True