mirror of
https://github.com/go-delve/delve.git
synced 2025-10-30 10:17:03 +08:00
Fix: track recurseLevel in readArray/readSlice
This fix helps avoid infinite recursion.
This commit is contained in:
13
_fixtures/testvariables2.go
Normal file
13
_fixtures/testvariables2.go
Normal file
@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "runtime"
|
||||
|
||||
type a struct {
|
||||
aas []a
|
||||
}
|
||||
|
||||
func main() {
|
||||
var aas = []a{{nil}}
|
||||
aas[0].aas = aas
|
||||
runtime.Breakpoint()
|
||||
}
|
||||
@ -522,7 +522,7 @@ func (thread *Thread) extractValueInternal(instructions []byte, addr int64, typ
|
||||
case t.StructName == "string":
|
||||
return thread.readString(ptraddress)
|
||||
case strings.HasPrefix(t.StructName, "[]"):
|
||||
return thread.readSlice(ptraddress, t)
|
||||
return thread.readSlice(ptraddress, t, recurseLevel)
|
||||
default:
|
||||
// Recursively call extractValue to grab
|
||||
// the value of all the members of the struct.
|
||||
@ -548,7 +548,7 @@ func (thread *Thread) extractValueInternal(instructions []byte, addr int64, typ
|
||||
return "{...}", nil
|
||||
}
|
||||
case *dwarf.ArrayType:
|
||||
return thread.readArray(ptraddress, t)
|
||||
return thread.readArray(ptraddress, t, recurseLevel)
|
||||
case *dwarf.ComplexType:
|
||||
return thread.readComplex(ptraddress, t.ByteSize)
|
||||
case *dwarf.IntType:
|
||||
@ -601,7 +601,7 @@ func (thread *Thread) readString(addr uintptr) (string, error) {
|
||||
return *(*string)(unsafe.Pointer(&val)), nil
|
||||
}
|
||||
|
||||
func (thread *Thread) readSlice(addr uintptr, t *dwarf.StructType) (string, error) {
|
||||
func (thread *Thread) readSlice(addr uintptr, t *dwarf.StructType, recurseLevel int) (string, error) {
|
||||
var sliceLen, sliceCap int64
|
||||
var arrayAddr uintptr
|
||||
var arrayType dwarf.Type
|
||||
@ -644,7 +644,7 @@ func (thread *Thread) readSlice(addr uintptr, t *dwarf.StructType) (string, erro
|
||||
if _, ok := arrayType.(*dwarf.PtrType); ok {
|
||||
stride = int64(thread.dbp.arch.PtrSize())
|
||||
}
|
||||
vals, err := thread.readArrayValues(arrayAddr, sliceLen, stride, arrayType)
|
||||
vals, err := thread.readArrayValues(arrayAddr, sliceLen, stride, arrayType, recurseLevel)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -652,9 +652,9 @@ func (thread *Thread) readSlice(addr uintptr, t *dwarf.StructType) (string, erro
|
||||
return fmt.Sprintf("[]%s len: %d, cap: %d, [%s]", arrayType, sliceLen, sliceCap, strings.Join(vals, ",")), nil
|
||||
}
|
||||
|
||||
func (thread *Thread) readArray(addr uintptr, t *dwarf.ArrayType) (string, error) {
|
||||
func (thread *Thread) readArray(addr uintptr, t *dwarf.ArrayType, recurseLevel int) (string, error) {
|
||||
if t.Count > 0 {
|
||||
vals, err := thread.readArrayValues(addr, t.Count, t.ByteSize/t.Count, t.Type)
|
||||
vals, err := thread.readArrayValues(addr, t.Count, t.ByteSize/t.Count, t.Type, recurseLevel)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@ -664,7 +664,7 @@ func (thread *Thread) readArray(addr uintptr, t *dwarf.ArrayType) (string, error
|
||||
return fmt.Sprintf("%s []", t), nil
|
||||
}
|
||||
|
||||
func (thread *Thread) readArrayValues(addr uintptr, count int64, stride int64, t dwarf.Type) ([]string, error) {
|
||||
func (thread *Thread) readArrayValues(addr uintptr, count int64, stride int64, t dwarf.Type, recurseLevel int) ([]string, error) {
|
||||
vals := make([]string, 0)
|
||||
|
||||
for i := int64(0); i < count; i++ {
|
||||
@ -674,7 +674,7 @@ func (thread *Thread) readArrayValues(addr uintptr, count int64, stride int64, t
|
||||
break
|
||||
}
|
||||
|
||||
val, err := thread.extractValue(nil, int64(addr+uintptr(i*stride)), t, false)
|
||||
val, err := thread.extractValueInternal(nil, int64(addr+uintptr(i*stride)), t, false, recurseLevel+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -216,3 +216,12 @@ func TestLocalVariables(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecursiveStructure(t *testing.T) {
|
||||
withTestProcess("testvariables2", t, func(p *Process, fixture protest.Fixture) {
|
||||
assertNoError(p.Continue(), t, "Continue()")
|
||||
v, err := p.EvalVariable("aas")
|
||||
assertNoError(err, t, "EvalVariable()")
|
||||
t.Logf("v: %v\n", v)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user