summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/runtime-gdb.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/runtime-gdb.py')
-rw-r--r--src/pkg/runtime/runtime-gdb.py39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/pkg/runtime/runtime-gdb.py b/src/pkg/runtime/runtime-gdb.py
index a96f3f382..dff4e2b83 100644
--- a/src/pkg/runtime/runtime-gdb.py
+++ b/src/pkg/runtime/runtime-gdb.py
@@ -91,8 +91,8 @@ class MapTypePrinter:
def traverse_hash(self, stab):
ptr = stab['entry'].address
- end = stab['end']
- while ptr < end:
+ last = stab['last']
+ while ptr <= last:
v = ptr.dereference()
ptr = ptr + 1
if v['hash'] == 0: continue
@@ -122,8 +122,8 @@ class ChanTypePrinter:
return str(self.val.type)
def children(self):
- # see chan.c chanbuf()
- et = [x.type for x in self.val['free'].type.target().fields() if x.name == 'elem'][0]
+ # see chan.c chanbuf(). et is the type stolen from hchan<T>::recvq->first->elem
+ et = [x.type for x in self.val['recvq']['first'].type.target().fields() if x.name == 'elem'][0]
ptr = (self.val.address + 1).cast(et.pointer())
for i in range(self.val["qcount"]):
j = (self.val["recvx"] + i) % self.val["dataqsiz"]
@@ -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: