]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: gdb support: gracefully handle not being able to find types
authorLuuk van Dijk <lvd@golang.org>
Fri, 23 Sep 2011 08:28:02 +0000 (10:28 +0200)
committerLuuk van Dijk <lvd@golang.org>
Fri, 23 Sep 2011 08:28:02 +0000 (10:28 +0200)
The Dwarf info has the full typenames, the go *struct runtime.commonType
has the short name.  A more permanent fix would link the two together
but this way the user gets useable stack traces for now.

R=rsc
CC=golang-dev
https://golang.org/cl/5097046

src/pkg/runtime/runtime-gdb.py

index a96f3f3828c32e6a84991225bb0310a6fd613cde..f815e102c1169346ba349c866186a015f88cd906 100644 (file)
@@ -187,6 +187,8 @@ def lookup_type(name):
 
 def iface_dtype(obj):
        "Decode type of the data field of an eface or iface struct."
+        # known issue: dtype_name decoded from runtime.commonType is "nested.Foo"
+        # but the dwarf table lists it as "full/path/to/nested.Foo"
 
        if is_iface(obj):
                go_type_ptr = obj['tab']['_type']
@@ -198,13 +200,30 @@ def iface_dtype(obj):
        ct = gdb.lookup_type("struct runtime.commonType").pointer()
        dynamic_go_type = go_type_ptr['ptr'].cast(ct).dereference()
        dtype_name = dynamic_go_type['string'].dereference()['str'].string()
-       type_size = int(dynamic_go_type['size'])
-       uintptr_size = int(dynamic_go_type['size'].type.sizeof)  # size is itself an uintptr
+
        dynamic_gdb_type = lookup_type(dtype_name)
-       if type_size > uintptr_size:
-               dynamic_gdb_type = dynamic_gdb_type.pointer()
+        if dynamic_gdb_type:
+               type_size = int(dynamic_go_type['size'])
+                uintptr_size = int(dynamic_go_type['size'].type.sizeof)  # size is itself an uintptr
+               if type_size > uintptr_size:
+                       dynamic_gdb_type = dynamic_gdb_type.pointer()
+
        return dynamic_gdb_type
 
+def iface_dtype_name(obj):
+       "Decode type name of the data field of an eface or iface struct."
+
+       if is_iface(obj):
+               go_type_ptr = obj['tab']['_type']
+       elif is_eface(obj):
+               go_type_ptr = obj['_type']
+       else:
+               return
+
+       ct = gdb.lookup_type("struct runtime.commonType").pointer()
+       dynamic_go_type = go_type_ptr['ptr'].cast(ct).dereference()
+       return dynamic_go_type['string'].dereference()['str'].string()
+
 
 class IfacePrinter:
        """Pretty print interface values
@@ -224,6 +243,10 @@ class IfacePrinter:
                        dtype = iface_dtype(self.val)
                except:
                        return "<bad dynamic type>"
+
+                if not dtype:  # trouble looking up, print something reasonable
+                       return "(%s)%s" % (iface_dtype_name(self.val), self.val['data'])
+
                try:
                        return self.val['data'].cast(dtype).dereference()
                except: