From 67ad85feec2fefecc827ca18c7d5ad7c50aa8e2c Mon Sep 17 00:00:00 2001 From: epipho Date: Mon, 19 Jan 2015 18:25:08 -0500 Subject: [PATCH] readString can now read strings of any length as well as sliced strings --- _fixtures/testvariables.go | 5 +++-- proctl/variables.go | 22 +++++++++++++++------- proctl/variables_test.go | 12 +++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/_fixtures/testvariables.go b/_fixtures/testvariables.go index 9516a16d..e39148c4 100644 --- a/_fixtures/testvariables.go +++ b/_fixtures/testvariables.go @@ -20,7 +20,7 @@ func barfoo() { func foobar(baz string, bar FooBar) { var ( - a1 = "foo" + a1 = "foofoofoofoofoofoo" a2 = 6 a3 = 7.23 a4 = [2]int{1, 2} @@ -29,6 +29,7 @@ func foobar(baz string, bar FooBar) { a7 = &FooBar{Baz: 5, Bur: "strum"} a8 = FooBar2{Bur: 10, Baz: "feh"} a9 = (*FooBar)(nil) + a10 = a1[2:5] neg = -1 i8 = int8(1) f32 = float32(1.2) @@ -36,7 +37,7 @@ func foobar(baz string, bar FooBar) { ) barfoo() - fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, baz, neg, i8, f32, i32, bar) + fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, baz, neg, i8, f32, i32, bar) } func main() { diff --git a/proctl/variables.go b/proctl/variables.go index 20a1ea48..5e8f194a 100644 --- a/proctl/variables.go +++ b/proctl/variables.go @@ -594,7 +594,7 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i case *dwarf.StructType: switch t.StructName { case "string": - return thread.readString(ptraddress, t.ByteSize) + return thread.readString(ptraddress) case "[]int": return thread.readIntSlice(ptraddress, t) default: @@ -623,21 +623,29 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i return "", fmt.Errorf("could not find value for type %s", typ) } -func (thread *ThreadContext) readString(addr uintptr, size int64) (string, error) { - // deref the pointer to the string - val, err := thread.readMemory(addr, uintptr(size)) +func (thread *ThreadContext) readString(addr uintptr) (string, error) { + // string data structure is always two ptrs in size. Addr, followed by len + // http://research.swtch.com/godata + + // read len + val, err := thread.readMemory(addr+ptrsize, ptrsize) + if err != nil { + return "", err + } + strlen := uintptr(binary.LittleEndian.Uint64(val)) + + // read addr + val, err = thread.readMemory(addr, ptrsize) if err != nil { return "", err } addr = uintptr(binary.LittleEndian.Uint64(val)) - val, err = thread.readMemory(addr, 16) + val, err = thread.readMemory(addr, strlen) if err != nil { return "", err } - i := bytes.IndexByte(val, 0x0) - val = val[:i] return *(*string)(unsafe.Pointer(&val)), nil } diff --git a/proctl/variables_test.go b/proctl/variables_test.go index 47003598..15d76a7e 100644 --- a/proctl/variables_test.go +++ b/proctl/variables_test.go @@ -37,7 +37,8 @@ func TestVariableEvaluation(t *testing.T) { } testcases := []varTest{ - {"a1", "foo", "struct string", nil}, + {"a1", "foofoofoofoofoofoo", "struct string", nil}, + {"a10", "ofo", "struct string", nil}, {"a2", "6", "int", nil}, {"a3", "7.23", "float64", nil}, {"a4", "[2]int [1 2]", "[2]int", nil}, @@ -61,7 +62,7 @@ func TestVariableEvaluation(t *testing.T) { } withTestProcess(executablePath, t, func(p *DebuggedProcess) { - pc, _, _ := p.GoSymTable.LineToPC(fp, 38) + pc, _, _ := p.GoSymTable.LineToPC(fp, 39) _, err := p.Break(pc) assertNoError(err, t, "Break() returned an error") @@ -92,7 +93,7 @@ func TestVariableFunctionScoping(t *testing.T) { } withTestProcess(executablePath, t, func(p *DebuggedProcess) { - pc, _, _ := p.GoSymTable.LineToPC(fp, 38) + pc, _, _ := p.GoSymTable.LineToPC(fp, 39) _, err := p.Break(pc) assertNoError(err, t, "Break() returned an error") @@ -156,7 +157,8 @@ func TestLocalVariables(t *testing.T) { }{ {(*ThreadContext).LocalVariables, []varTest{ - {"a1", "foo", "struct string", nil}, + {"a1", "foofoofoofoofoofoo", "struct string", nil}, + {"a10", "ofo", "struct string", nil}, {"a2", "6", "int", nil}, {"a3", "7.23", "float64", nil}, {"a4", "[2]int [1 2]", "[2]int", nil}, @@ -176,7 +178,7 @@ func TestLocalVariables(t *testing.T) { } withTestProcess(executablePath, t, func(p *DebuggedProcess) { - pc, _, _ := p.GoSymTable.LineToPC(fp, 38) + pc, _, _ := p.GoSymTable.LineToPC(fp, 39) _, err := p.Break(pc) assertNoError(err, t, "Break() returned an error") -- GitLab