diff --git a/_fixtures/testvariables.go b/_fixtures/testvariables.go index e39148c466164469aa6e8ded2343dae8a781dfc6..fb27dae3d1a935cab5fc2abc05a14c24a7bb8ee2 100644 --- a/_fixtures/testvariables.go +++ b/_fixtures/testvariables.go @@ -30,14 +30,21 @@ func foobar(baz string, bar FooBar) { a8 = FooBar2{Bur: 10, Baz: "feh"} a9 = (*FooBar)(nil) a10 = a1[2:5] + b1 = true + b2 = false neg = -1 i8 = int8(1) + u8 = uint8(255) + u16 = uint16(65535) + u32 = uint32(4294967295) + u64 = uint64(18446744073709551615) + up = uintptr(5) f32 = float32(1.2) i32 = [2]int32{1, 2} ) barfoo() - fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, baz, neg, i8, f32, i32, bar) + fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, b1, b2, baz, neg, i8, u8, u16, u32, u64, up, f32, i32, bar) } func main() { diff --git a/proctl/variables.go b/proctl/variables.go index 5e8f194a13196d45241ce517eafab654d9b1d85f..1be8a1918bb953560b434facbe885d337bc38188 100644 --- a/proctl/variables.go +++ b/proctl/variables.go @@ -616,8 +616,12 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i return thread.readIntArray(ptraddress, t) case *dwarf.IntType: return thread.readInt(ptraddress, t.ByteSize) + case *dwarf.UintType: + return thread.readUint(ptraddress, t.ByteSize) case *dwarf.FloatType: return thread.readFloat(ptraddress, t.ByteSize) + case *dwarf.BoolType: + return thread.readBool(ptraddress) } return "", fmt.Errorf("could not find value for type %s", typ) @@ -693,7 +697,7 @@ func (thread *ThreadContext) readIntArray(addr uintptr, t *dwarf.ArrayType) (str } func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) { - var n int + var n int64 val, err := thread.readMemory(addr, uintptr(size)) if err != nil { @@ -702,16 +706,38 @@ func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) { switch size { case 1: - n = int(val[0]) + n = int64(val[0]) case 2: - n = int(binary.LittleEndian.Uint16(val)) + n = int64(binary.LittleEndian.Uint16(val)) case 4: - n = int(binary.LittleEndian.Uint32(val)) + n = int64(binary.LittleEndian.Uint32(val)) case 8: - n = int(binary.LittleEndian.Uint64(val)) + n = int64(binary.LittleEndian.Uint64(val)) } - return strconv.Itoa(n), nil + return strconv.FormatInt(n, 10), nil +} + +func (thread *ThreadContext) readUint(addr uintptr, size int64) (string, error) { + var n uint64 + + val, err := thread.readMemory(addr, uintptr(size)) + if err != nil { + return "", err + } + + switch size { + case 1: + n = uint64(val[0]) + case 2: + n = uint64(binary.LittleEndian.Uint16(val)) + case 4: + n = uint64(binary.LittleEndian.Uint32(val)) + case 8: + n = uint64(binary.LittleEndian.Uint64(val)) + } + + return strconv.FormatUint(n, 10), nil } func (thread *ThreadContext) readFloat(addr uintptr, size int64) (string, error) { @@ -735,6 +761,19 @@ func (thread *ThreadContext) readFloat(addr uintptr, size int64) (string, error) return "", fmt.Errorf("could not read float") } +func (thread *ThreadContext) readBool(addr uintptr) (string, error) { + val, err := thread.readMemory(addr, uintptr(1)) + if err != nil { + return "", err + } + + if val[0] == 0 { + return "false", nil + } + + return "true", nil +} + func (thread *ThreadContext) readMemory(addr uintptr, size uintptr) ([]byte, error) { buf := make([]byte, size) @@ -770,7 +809,8 @@ func (thread *ThreadContext) variablesByTag(tag dwarf.Tag) ([]*Variable, error) if entry.Tag == tag { val, err := thread.extractVariableFromEntry(entry) if err != nil { - return nil, err + // skip variables that we can't parse yet + continue } vars = append(vars, val) diff --git a/proctl/variables_test.go b/proctl/variables_test.go index 15d76a7edb0f2a8c1cb55dff7cec0eccb611aff0..ab1d1202a81618df2aaf7a8ed4631a21e0e49f40 100644 --- a/proctl/variables_test.go +++ b/proctl/variables_test.go @@ -49,7 +49,6 @@ func TestVariableEvaluation(t *testing.T) { {"a9", "*main.FooBar nil", "*main.FooBar", nil}, {"baz", "bazburzum", "struct string", nil}, {"neg", "-1", "int", nil}, - {"i8", "1", "int8", nil}, {"f32", "1.2", "float32", nil}, {"a6.Baz", "8", "int", nil}, {"a7.Baz", "5", "int", nil}, @@ -58,11 +57,18 @@ func TestVariableEvaluation(t *testing.T) { {"a9.NonExistent", "nil", "int", errors.New("a9 has no member NonExistent")}, {"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, // reread variable after member {"i32", "[2]int32 [1 2]", "[2]int32", nil}, + {"b1", "true", "bool", nil}, + {"b2", "false", "bool", nil}, {"i8", "1", "int8", nil}, + {"u16", "65535", "uint16", nil}, + {"u32", "4294967295", "uint32", nil}, + {"u64", "18446744073709551615", "uint64", nil}, + {"u8", "255", "uint8", nil}, + {"up", "5", "uintptr", nil}, {"NonExistent", "", "", errors.New("could not find symbol value for NonExistent")}, } withTestProcess(executablePath, t, func(p *DebuggedProcess) { - pc, _, _ := p.GoSymTable.LineToPC(fp, 39) + pc, _, _ := p.GoSymTable.LineToPC(fp, 46) _, err := p.Break(pc) assertNoError(err, t, "Break() returned an error") @@ -93,7 +99,7 @@ func TestVariableFunctionScoping(t *testing.T) { } withTestProcess(executablePath, t, func(p *DebuggedProcess) { - pc, _, _ := p.GoSymTable.LineToPC(fp, 39) + pc, _, _ := p.GoSymTable.LineToPC(fp, 46) _, err := p.Break(pc) assertNoError(err, t, "Break() returned an error") @@ -167,10 +173,17 @@ func TestLocalVariables(t *testing.T) { {"a7", "*main.FooBar {Baz: 5, Bur: strum}", "*main.FooBar", nil}, {"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, {"a9", "*main.FooBar nil", "*main.FooBar", nil}, + {"b1", "true", "bool", nil}, + {"b2", "false", "bool", nil}, {"f32", "1.2", "float32", nil}, {"i32", "[2]int32 [1 2]", "[2]int32", nil}, {"i8", "1", "int8", nil}, - {"neg", "-1", "int", nil}}}, + {"neg", "-1", "int", nil}, + {"u16", "65535", "uint16", nil}, + {"u32", "4294967295", "uint32", nil}, + {"u64", "18446744073709551615", "uint64", nil}, + {"u8", "255", "uint8", nil}, + {"up", "5", "uintptr", nil}}}, {(*ThreadContext).FunctionArguments, []varTest{ {"bar", "main.FooBar {Baz: 10, Bur: lorem}", "main.FooBar", nil}, @@ -178,7 +191,7 @@ func TestLocalVariables(t *testing.T) { } withTestProcess(executablePath, t, func(p *DebuggedProcess) { - pc, _, _ := p.GoSymTable.LineToPC(fp, 39) + pc, _, _ := p.GoSymTable.LineToPC(fp, 46) _, err := p.Break(pc) assertNoError(err, t, "Break() returned an error")