diff --git a/proctl/proctl_linux_amd64.go b/proctl/proctl_linux_amd64.go index 33bc247f..c036a603 100644 --- a/proctl/proctl_linux_amd64.go +++ b/proctl/proctl_linux_amd64.go @@ -12,6 +12,7 @@ import ( "os" "strconv" "syscall" + "unsafe" "github.com/derekparker/dbg/dwarf/frame" "github.com/derekparker/dbg/dwarf/line" @@ -376,6 +377,8 @@ func (dbp *DebuggedProcess) extractValue(instructions []byte, typ interface{}) ( offset := uintptr(int64(regs.Rsp) + off) switch typ.(type) { + case *dwarf.StructType: + return dbp.readString(offset) case *dwarf.IntType: return dbp.readInt(offset) case *dwarf.FloatType: @@ -385,6 +388,25 @@ func (dbp *DebuggedProcess) extractValue(instructions []byte, typ interface{}) ( return "", fmt.Errorf("could not find value for type %s", typ) } +func (dbp *DebuggedProcess) readString(addr uintptr) (string, error) { + val, err := dbp.readMemory(addr, 8) + if err != nil { + return "", err + } + + // deref the pointer to the string + addr = uintptr(binary.LittleEndian.Uint64(val)) + val, err = dbp.readMemory(addr, 16) + if err != nil { + return "", err + } + + i := bytes.IndexByte(val, 0x0) + val = val[:i] + str := *(*string)(unsafe.Pointer(&val)) + return str, nil +} + func (dbp *DebuggedProcess) readInt(addr uintptr) (string, error) { val, err := dbp.readMemory(addr, 8) if err != nil { diff --git a/proctl/proctl_test.go b/proctl/proctl_test.go index 4961ea9c..523bb350 100644 --- a/proctl/proctl_test.go +++ b/proctl/proctl_test.go @@ -231,6 +231,7 @@ func TestVariableEvaluation(t *testing.T) { value string varType string }{ + {"a1", "foo", "struct string"}, {"a2", "6", "int"}, {"a3", "7.23", "float64"}, } @@ -257,7 +258,7 @@ func TestVariableEvaluation(t *testing.T) { } if variable.Value != tc.value { - t.Fatalf("Expected %s got %s\n", tc.value, variable.Value) + t.Fatalf("Expected %#v got %#v\n", tc.value, variable.Value) } } })