mirror of
https://github.com/golang/go
synced 2024-09-28 18:14:29 -06:00
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
This commit is contained in:
parent
7249fa773a
commit
46ed89b7a3
@ -187,6 +187,8 @@ def lookup_type(name):
|
|||||||
|
|
||||||
def iface_dtype(obj):
|
def iface_dtype(obj):
|
||||||
"Decode type of the data field of an eface or iface struct."
|
"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):
|
if is_iface(obj):
|
||||||
go_type_ptr = obj['tab']['_type']
|
go_type_ptr = obj['tab']['_type']
|
||||||
@ -198,13 +200,30 @@ def iface_dtype(obj):
|
|||||||
ct = gdb.lookup_type("struct runtime.commonType").pointer()
|
ct = gdb.lookup_type("struct runtime.commonType").pointer()
|
||||||
dynamic_go_type = go_type_ptr['ptr'].cast(ct).dereference()
|
dynamic_go_type = go_type_ptr['ptr'].cast(ct).dereference()
|
||||||
dtype_name = dynamic_go_type['string'].dereference()['str'].string()
|
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)
|
dynamic_gdb_type = lookup_type(dtype_name)
|
||||||
if type_size > uintptr_size:
|
if dynamic_gdb_type:
|
||||||
dynamic_gdb_type = dynamic_gdb_type.pointer()
|
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
|
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:
|
class IfacePrinter:
|
||||||
"""Pretty print interface values
|
"""Pretty print interface values
|
||||||
@ -224,6 +243,10 @@ class IfacePrinter:
|
|||||||
dtype = iface_dtype(self.val)
|
dtype = iface_dtype(self.val)
|
||||||
except:
|
except:
|
||||||
return "<bad dynamic type>"
|
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:
|
try:
|
||||||
return self.val['data'].cast(dtype).dereference()
|
return self.val['data'].cast(dtype).dereference()
|
||||||
except:
|
except:
|
||||||
|
Loading…
Reference in New Issue
Block a user