diff --git a/_fixtures/testvariables3.go b/_fixtures/testvariables3.go index f4090684..f0d816d2 100644 --- a/_fixtures/testvariables3.go +++ b/_fixtures/testvariables3.go @@ -3,6 +3,7 @@ package main import ( "fmt" "runtime" + "unsafe" ) type astruct struct { @@ -91,11 +92,12 @@ func main() { var mnil map[string]astruct = nil m2 := map[int]*astruct{1: &astruct{10, 11}} m3 := map[astruct]int{{1, 1}: 42, {2, 2}: 43} + up1 := unsafe.Pointer(&i1) var amb1 = 1 runtime.Breakpoint() for amb1 := 0; amb1 < 10; amb1++ { fmt.Println(amb1) } - fmt.Println(i1, i2, i3, p1, amb1, s1, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3) + fmt.Println(i1, i2, i3, p1, amb1, s1, a1, p2, p3, s2, as1, str1, f1, fn1, fn2, nilslice, nilptr, ch1, chnil, m1, mnil, m2, m3, up1) } diff --git a/proc/variables.go b/proc/variables.go index 428c8c70..40114771 100644 --- a/proc/variables.go +++ b/proc/variables.go @@ -130,10 +130,13 @@ func newVariable(name string, addr uintptr, dwarfType dwarf.Type, thread *Thread switch t := v.RealType.(type) { case *dwarf.PtrType: structtyp, isstruct := t.Type.(*dwarf.StructType) + _, isvoid := t.Type.(*dwarf.VoidType) if isstruct && strings.HasPrefix(structtyp.StructName, "hchan<") { v.Kind = reflect.Chan } else if isstruct && strings.HasPrefix(structtyp.StructName, "hash<") { v.Kind = reflect.Map + } else if isvoid { + v.Kind = reflect.UnsafePointer } else { v.Kind = reflect.Ptr } @@ -711,7 +714,7 @@ func (v *Variable) loadValueInternal(recurseLevel int) { } v.loaded = true switch v.Kind { - case reflect.Ptr: + case reflect.Ptr, reflect.UnsafePointer: v.Len = 1 v.Children = []Variable{*v.maybeDereference()} // Don't increase the recursion level when dereferencing pointers diff --git a/service/api/prettyprint.go b/service/api/prettyprint.go index 2879d214..dacf889b 100644 --- a/service/api/prettyprint.go +++ b/service/api/prettyprint.go @@ -53,6 +53,8 @@ func (v *Variable) writeTo(buf *bytes.Buffer, top, newlines, includeType bool, i fmt.Fprintf(buf, "*") v.Children[0].writeTo(buf, false, newlines, includeType, indent) } + case reflect.UnsafePointer: + fmt.Fprintf(buf, "unsafe.Pointer(0x%x)", v.Children[0].Addr) case reflect.String: v.writeStringTo(buf) case reflect.Chan: diff --git a/service/test/variables_test.go b/service/test/variables_test.go index 0ea9907f..03fa57fb 100644 --- a/service/test/variables_test.go +++ b/service/test/variables_test.go @@ -565,5 +565,16 @@ func TestMapEvaluation(t *testing.T) { t.Fatalf("Wrong number of children (after slicing): %d", len(m1sliced.Children)/2) } }) - +} + +func TestUnsafePointer(t *testing.T) { + withTestProcess("testvariables3", t, func(p *proc.Process, fixture protest.Fixture) { + assertNoError(p.Continue(), t, "Continue() returned an error") + up1v, err := evalVariable(p, "up1") + assertNoError(err, t, "EvalVariable(up1)") + up1 := api.ConvertVar(up1v) + if ss := up1.SinglelineString(); !strings.HasPrefix(ss, "unsafe.Pointer(") { + t.Fatalf("wrong value for up1: %s", ss) + } + }) }