mirror of
https://github.com/go-delve/delve.git
synced 2025-10-30 10:17:03 +08:00
Added limit to array size (64) and struct member recursion (2) when printing
This commit is contained in:
@ -13,6 +13,11 @@ type FooBar2 struct {
|
||||
Baz string
|
||||
}
|
||||
|
||||
type Nest struct {
|
||||
Level int
|
||||
Nest *Nest
|
||||
}
|
||||
|
||||
func barfoo() {
|
||||
a1 := "bur"
|
||||
fmt.Println(a1)
|
||||
@ -45,10 +50,12 @@ func foobar(baz string, bar FooBar) {
|
||||
f32 = float32(1.2)
|
||||
i32 = [2]int32{1, 2}
|
||||
f = barfoo
|
||||
ms = Nest{0, &Nest{1, &Nest{2, &Nest{3, &Nest{4, nil}}}}} // Test recursion capping
|
||||
ba = make([]int, 200, 200) // Test array size capping
|
||||
)
|
||||
|
||||
barfoo()
|
||||
fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, b1, b2, baz, neg, i8, u8, u16, u32, u64, up, f32, i32, bar, f)
|
||||
fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, b1, b2, baz, neg, i8, u8, u16, u32, u64, up, f32, i32, bar, f, ms, ba)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
@ -13,6 +13,11 @@ import (
|
||||
"github.com/derekparker/delve/dwarf/reader"
|
||||
)
|
||||
|
||||
const (
|
||||
maxVariableRecurse = 1
|
||||
maxArrayValues = 64
|
||||
)
|
||||
|
||||
type Variable struct {
|
||||
Name string
|
||||
Value string
|
||||
@ -558,6 +563,10 @@ func (thread *ThreadContext) extractVariableDataAddress(entry *dwarf.Entry, read
|
||||
// We execute the stack program described in the DW_OP_* instruction stream, and
|
||||
// then grab the value from the other processes memory.
|
||||
func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ interface{}, printStructName bool) (string, error) {
|
||||
return thread.extractValueInternal(instructions, addr, typ, printStructName, 0)
|
||||
}
|
||||
|
||||
func (thread *ThreadContext) extractValueInternal(instructions []byte, addr int64, typ interface{}, printStructName bool, recurseLevel int) (string, error) {
|
||||
var err error
|
||||
|
||||
if addr == 0 {
|
||||
@ -590,7 +599,8 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i
|
||||
return fmt.Sprintf("%s nil", t.String()), nil
|
||||
}
|
||||
|
||||
val, err := thread.extractValue(nil, intaddr, t.Type, printStructName)
|
||||
// Don't increase the recursion level when dereferencing pointers
|
||||
val, err := thread.extractValueInternal(nil, intaddr, t.Type, printStructName, recurseLevel)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -605,9 +615,10 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i
|
||||
default:
|
||||
// Recursively call extractValue to grab
|
||||
// the value of all the members of the struct.
|
||||
if recurseLevel <= maxVariableRecurse {
|
||||
fields := make([]string, 0, len(t.Field))
|
||||
for _, field := range t.Field {
|
||||
val, err := thread.extractValue(nil, field.ByteOffset+addr, field.Type, printStructName)
|
||||
val, err := thread.extractValueInternal(nil, field.ByteOffset+addr, field.Type, printStructName, recurseLevel+1)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -616,9 +627,14 @@ func (thread *ThreadContext) extractValue(instructions []byte, addr int64, typ i
|
||||
}
|
||||
if printStructName {
|
||||
return fmt.Sprintf("%s {%s}", t.StructName, strings.Join(fields, ", ")), nil
|
||||
} else {
|
||||
}
|
||||
return fmt.Sprintf("{%s}", strings.Join(fields, ", ")), nil
|
||||
}
|
||||
// no fields
|
||||
if printStructName {
|
||||
return fmt.Sprintf("%s {...}", t.StructName), nil
|
||||
}
|
||||
return "{...}", nil
|
||||
}
|
||||
case *dwarf.ArrayType:
|
||||
return thread.readArray(ptraddress, t)
|
||||
@ -736,6 +752,12 @@ func (thread *ThreadContext) readArrayValues(addr uintptr, count int64, stride i
|
||||
vals := make([]string, 0)
|
||||
|
||||
for i := int64(0); i < count; i++ {
|
||||
// Cap number of elements
|
||||
if i >= maxArrayValues {
|
||||
vals = append(vals, fmt.Sprintf("...+%d more", count-maxArrayValues))
|
||||
break
|
||||
}
|
||||
|
||||
val, err := thread.extractValue(nil, int64(addr+uintptr(i*stride)), t, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@ -68,11 +68,13 @@ func TestVariableEvaluation(t *testing.T) {
|
||||
{"u8", "255", "uint8", nil},
|
||||
{"up", "5", "uintptr", nil},
|
||||
{"f", "main.barfoo", "func()", nil},
|
||||
{"ba", "[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]", "struct []int", nil},
|
||||
{"ms", "main.Nest {Level: 0, Nest: *main.Nest {Level: 1, Nest: *main.Nest {...}}}", "main.Nest", nil},
|
||||
{"NonExistent", "", "", errors.New("could not find symbol value for NonExistent")},
|
||||
}
|
||||
|
||||
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 50)
|
||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 57)
|
||||
|
||||
_, err := p.Break(pc)
|
||||
assertNoError(err, t, "Break() returned an error")
|
||||
@ -103,7 +105,7 @@ func TestVariableFunctionScoping(t *testing.T) {
|
||||
}
|
||||
|
||||
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 50)
|
||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 57)
|
||||
|
||||
_, err := p.Break(pc)
|
||||
assertNoError(err, t, "Break() returned an error")
|
||||
@ -118,7 +120,7 @@ func TestVariableFunctionScoping(t *testing.T) {
|
||||
assertNoError(err, t, "Unable to find variable a1")
|
||||
|
||||
// Move scopes, a1 exists here by a2 does not
|
||||
pc, _, _ = p.GoSymTable.LineToPC(fp, 18)
|
||||
pc, _, _ = p.GoSymTable.LineToPC(fp, 23)
|
||||
|
||||
_, err = p.Break(pc)
|
||||
assertNoError(err, t, "Break() returned an error")
|
||||
@ -182,10 +184,12 @@ func TestLocalVariables(t *testing.T) {
|
||||
{"a9", "*main.FooBar nil", "*main.FooBar", nil},
|
||||
{"b1", "true", "bool", nil},
|
||||
{"b2", "false", "bool", nil},
|
||||
{"ba", "[]int len: 200, cap: 200, [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,...+136 more]", "struct []int", nil},
|
||||
{"f", "main.barfoo", "func()", nil},
|
||||
{"f32", "1.2", "float32", nil},
|
||||
{"i32", "[2]int32 [1,2]", "[2]int32", nil},
|
||||
{"i8", "1", "int8", nil},
|
||||
{"ms", "main.Nest {Level: 0, Nest: *main.Nest {Level: 1, Nest: *main.Nest {...}}}", "main.Nest", nil},
|
||||
{"neg", "-1", "int", nil},
|
||||
{"u16", "65535", "uint16", nil},
|
||||
{"u32", "4294967295", "uint32", nil},
|
||||
@ -199,7 +203,7 @@ func TestLocalVariables(t *testing.T) {
|
||||
}
|
||||
|
||||
withTestProcess(executablePath, t, func(p *DebuggedProcess) {
|
||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 50)
|
||||
pc, _, _ := p.GoSymTable.LineToPC(fp, 57)
|
||||
|
||||
_, err := p.Break(pc)
|
||||
assertNoError(err, t, "Break() returned an error")
|
||||
|
||||
Reference in New Issue
Block a user