mirror of
https://github.com/go-delve/delve.git
synced 2025-10-30 18:27:37 +08:00
Support for uint and boolean types
This commit is contained in:
@ -30,14 +30,21 @@ func foobar(baz string, bar FooBar) {
|
|||||||
a8 = FooBar2{Bur: 10, Baz: "feh"}
|
a8 = FooBar2{Bur: 10, Baz: "feh"}
|
||||||
a9 = (*FooBar)(nil)
|
a9 = (*FooBar)(nil)
|
||||||
a10 = a1[2:5]
|
a10 = a1[2:5]
|
||||||
|
b1 = true
|
||||||
|
b2 = false
|
||||||
neg = -1
|
neg = -1
|
||||||
i8 = int8(1)
|
i8 = int8(1)
|
||||||
|
u8 = uint8(255)
|
||||||
|
u16 = uint16(65535)
|
||||||
|
u32 = uint32(4294967295)
|
||||||
|
u64 = uint64(18446744073709551615)
|
||||||
|
up = uintptr(5)
|
||||||
f32 = float32(1.2)
|
f32 = float32(1.2)
|
||||||
i32 = [2]int32{1, 2}
|
i32 = [2]int32{1, 2}
|
||||||
)
|
)
|
||||||
|
|
||||||
barfoo()
|
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() {
|
func main() {
|
||||||
|
|||||||
@ -616,8 +616,12 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i
|
|||||||
return thread.readIntArray(ptraddress, t)
|
return thread.readIntArray(ptraddress, t)
|
||||||
case *dwarf.IntType:
|
case *dwarf.IntType:
|
||||||
return thread.readInt(ptraddress, t.ByteSize)
|
return thread.readInt(ptraddress, t.ByteSize)
|
||||||
|
case *dwarf.UintType:
|
||||||
|
return thread.readUint(ptraddress, t.ByteSize)
|
||||||
case *dwarf.FloatType:
|
case *dwarf.FloatType:
|
||||||
return thread.readFloat(ptraddress, t.ByteSize)
|
return thread.readFloat(ptraddress, t.ByteSize)
|
||||||
|
case *dwarf.BoolType:
|
||||||
|
return thread.readBool(ptraddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", fmt.Errorf("could not find value for type %s", typ)
|
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) {
|
func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) {
|
||||||
var n int
|
var n int64
|
||||||
|
|
||||||
val, err := thread.readMemory(addr, uintptr(size))
|
val, err := thread.readMemory(addr, uintptr(size))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -702,16 +706,38 @@ func (thread *ThreadContext) readInt(addr uintptr, size int64) (string, error) {
|
|||||||
|
|
||||||
switch size {
|
switch size {
|
||||||
case 1:
|
case 1:
|
||||||
n = int(val[0])
|
n = int64(val[0])
|
||||||
case 2:
|
case 2:
|
||||||
n = int(binary.LittleEndian.Uint16(val))
|
n = int64(binary.LittleEndian.Uint16(val))
|
||||||
case 4:
|
case 4:
|
||||||
n = int(binary.LittleEndian.Uint32(val))
|
n = int64(binary.LittleEndian.Uint32(val))
|
||||||
case 8:
|
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) {
|
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")
|
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) {
|
func (thread *ThreadContext) readMemory(addr uintptr, size uintptr) ([]byte, error) {
|
||||||
buf := make([]byte, size)
|
buf := make([]byte, size)
|
||||||
|
|
||||||
@ -770,7 +809,8 @@ func (thread *ThreadContext) variablesByTag(tag dwarf.Tag) ([]*Variable, error)
|
|||||||
if entry.Tag == tag {
|
if entry.Tag == tag {
|
||||||
val, err := thread.extractVariableFromEntry(entry)
|
val, err := thread.extractVariableFromEntry(entry)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
// skip variables that we can't parse yet
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
vars = append(vars, val)
|
vars = append(vars, val)
|
||||||
|
|||||||
@ -49,7 +49,6 @@ func TestVariableEvaluation(t *testing.T) {
|
|||||||
{"a9", "*main.FooBar nil", "*main.FooBar", nil},
|
{"a9", "*main.FooBar nil", "*main.FooBar", nil},
|
||||||
{"baz", "bazburzum", "struct string", nil},
|
{"baz", "bazburzum", "struct string", nil},
|
||||||
{"neg", "-1", "int", nil},
|
{"neg", "-1", "int", nil},
|
||||||
{"i8", "1", "int8", nil},
|
|
||||||
{"f32", "1.2", "float32", nil},
|
{"f32", "1.2", "float32", nil},
|
||||||
{"a6.Baz", "8", "int", nil},
|
{"a6.Baz", "8", "int", nil},
|
||||||
{"a7.Baz", "5", "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")},
|
{"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
|
{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil}, // reread variable after member
|
||||||
{"i32", "[2]int32 [1 2]", "[2]int32", nil},
|
{"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")},
|
{"NonExistent", "", "", errors.New("could not find symbol value for NonExistent")},
|
||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
||||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 39)
|
pc, _, _ := p.GoSymTable.LineToPC(fp, 46)
|
||||||
|
|
||||||
_, err := p.Break(pc)
|
_, err := p.Break(pc)
|
||||||
assertNoError(err, t, "Break() returned an error")
|
assertNoError(err, t, "Break() returned an error")
|
||||||
@ -93,7 +99,7 @@ func TestVariableFunctionScoping(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
||||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 39)
|
pc, _, _ := p.GoSymTable.LineToPC(fp, 46)
|
||||||
|
|
||||||
_, err := p.Break(pc)
|
_, err := p.Break(pc)
|
||||||
assertNoError(err, t, "Break() returned an error")
|
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},
|
{"a7", "*main.FooBar {Baz: 5, Bur: strum}", "*main.FooBar", nil},
|
||||||
{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil},
|
{"a8", "main.FooBar2 {Bur: 10, Baz: feh}", "main.FooBar2", nil},
|
||||||
{"a9", "*main.FooBar nil", "*main.FooBar", nil},
|
{"a9", "*main.FooBar nil", "*main.FooBar", nil},
|
||||||
|
{"b1", "true", "bool", nil},
|
||||||
|
{"b2", "false", "bool", nil},
|
||||||
{"f32", "1.2", "float32", nil},
|
{"f32", "1.2", "float32", nil},
|
||||||
{"i32", "[2]int32 [1 2]", "[2]int32", nil},
|
{"i32", "[2]int32 [1 2]", "[2]int32", nil},
|
||||||
{"i8", "1", "int8", 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,
|
{(*ThreadContext).FunctionArguments,
|
||||||
[]varTest{
|
[]varTest{
|
||||||
{"bar", "main.FooBar {Baz: 10, Bur: lorem}", "main.FooBar", nil},
|
{"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) {
|
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
||||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 39)
|
pc, _, _ := p.GoSymTable.LineToPC(fp, 46)
|
||||||
|
|
||||||
_, err := p.Break(pc)
|
_, err := p.Break(pc)
|
||||||
assertNoError(err, t, "Break() returned an error")
|
assertNoError(err, t, "Break() returned an error")
|
||||||
|
|||||||
Reference in New Issue
Block a user