view.py fixes, more samples
authorJorge Gorbe <j.gorbe@stcsl.es>
Fri, 30 Nov 2012 13:37:44 +0000 (14:37 +0100)
committerJorge Gorbe <j.gorbe@stcsl.es>
Fri, 30 Nov 2012 13:37:44 +0000 (14:37 +0100)
samples/array.cc [new file with mode: 0644]
samples/loop.c [new file with mode: 0644]
samples/plotarray.py [new file with mode: 0644]
samples/plotsimple.py [new file with mode: 0644]
samples/test-ref.cc [new file with mode: 0644]
samples/test.d [new file with mode: 0644]
samples/view.py

diff --git a/samples/array.cc b/samples/array.cc
new file mode 100644 (file)
index 0000000..1bd9587
--- /dev/null
@@ -0,0 +1,19 @@
+#include <cstdlib>
+#include <ctime>
+#include <cmath>
+
+int main(int argc, char **argv) {
+    const int N=200;
+    double array[N];
+    double *sine = new double[N];
+
+    srand(time(NULL));
+
+    for (int i=0; i < N; i++) {
+        array[i] = rand()/(double)RAND_MAX;
+        sine[i] = sin(2*M_PI*i/(double)N);
+    }
+
+    delete[] sine;
+    return 0;
+}
diff --git a/samples/loop.c b/samples/loop.c
new file mode 100644 (file)
index 0000000..700049c
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct snode {
+       int value;
+        float blah;
+       struct snode *next;
+} node;
+
+void add(node **head, int x) {
+       node *n = malloc(sizeof(node));
+       n->value = x;
+        n->blah = 1234.0f;
+       n->next = *head;
+       *head = n;
+}
+
+int main() {
+       node *list = NULL;
+       add(&list, 10);
+       add(&list, 20);
+       add(&list, 30);
+       add(&list, 99);
+
+        // close the loop!
+        list->next->next->next->next = list;
+}
+
diff --git a/samples/plotarray.py b/samples/plotarray.py
new file mode 100644 (file)
index 0000000..5d4afdb
--- /dev/null
@@ -0,0 +1,44 @@
+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()
+
+
diff --git a/samples/plotsimple.py b/samples/plotsimple.py
new file mode 100644 (file)
index 0000000..ffaee53
--- /dev/null
@@ -0,0 +1,19 @@
+import gdb
+import matplotlib.pyplot as plt
+
+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])
+        t = v.type.strip_typedefs()
+        n = t.sizeof / t.target().sizeof
+        l = [float(v[i]) for i in range(n)]
+        plt.plot(l)
+        plt.show()
+        
+PlotterCommand()
+
diff --git a/samples/test-ref.cc b/samples/test-ref.cc
new file mode 100644 (file)
index 0000000..06f8a16
--- /dev/null
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct snode {
+       int value;
+        float blah;
+       struct snode *next;
+} node;
+
+void add(node **head, int x) {
+       node *n = (node*) malloc(sizeof(node));
+       n->value = x;
+        n->blah = 1234.0f;
+       n->next = *head;
+       *head = n;
+}
+
+int main() {
+       node *list = NULL;
+       add(&list, 10);
+       add(&list, 20);
+       add(&list, 30);
+       add(&list, 99);
+
+        node &l2 = *list;
+        l2.blah=99.0f;
+}
+
diff --git a/samples/test.d b/samples/test.d
new file mode 100644 (file)
index 0000000..8117c49
--- /dev/null
@@ -0,0 +1,16 @@
+import std.stdio;
+
+class S 
+{ 
+    S next;
+}
+
+
+void main() 
+{ 
+    S s = new S();
+    s.next = new S();
+    s.next.next = new S();
+
+}
+
index 5820da9a6124494552a376159c56ec8510ff8587..0016ee31a3c18b3a4b50a7f05c2b80167f4848fa 100644 (file)
@@ -66,9 +66,9 @@ def find_outgoing_pointers(value):
                 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:
@@ -204,8 +204,8 @@ class GraphViewer(gtk.Layout):
         # 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:
@@ -261,6 +261,7 @@ class GraphViewer(gtk.Layout):
         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"
@@ -394,11 +395,11 @@ class ViewerWindow(gtk.Window):
     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)
@@ -414,7 +415,7 @@ def visit_values(node_dict, value, x, y, recursion_level):
         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
@@ -422,16 +423,15 @@ def visit_values(node_dict, value, x, y, recursion_level):
     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)
@@ -466,10 +466,10 @@ def fill_node_connections(nodes, addr, value):
             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:
@@ -514,7 +514,7 @@ class ViewerCommand(gdb.Command):
             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