runtime: gdb support: gracefully handle not being able to find types

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
diff --git a/src/pkg/runtime/runtime-gdb.py b/src/pkg/runtime/runtime-gdb.py
index a96f3f3..f815e10 100644
--- a/src/pkg/runtime/runtime-gdb.py
+++ b/src/pkg/runtime/runtime-gdb.py
@@ -187,6 +187,8 @@
 
 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 @@
 	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 @@
 			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: