proc: disable caching for variables with an extended location

Our current frame caching strategy doesn't handle extended locations
expressions correctly, disable it on variables that don't have a simple
address.
This commit is contained in:
aarzilli
2018-01-27 16:50:18 +01:00
committed by Derek Parker
parent 03139e8f62
commit 62fe792bfd
3 changed files with 20 additions and 2 deletions

View File

@ -128,6 +128,7 @@ func TestDwarfExprComposite(t *testing.T) {
testCases := map[string]uint16{
"pair.k": 0x8765,
"pair.v": 0x5678,
"n": 42,
}
const stringVal = "this is a string"
@ -163,6 +164,7 @@ func TestDwarfExprComposite(t *testing.T) {
dwb.AddVariable("s", stringoff, dwarfbuilder.LocationBlock(
op.DW_OP_reg1, op.DW_OP_piece, uint(8),
op.DW_OP_reg0, op.DW_OP_piece, uint(8)))
dwb.AddVariable("n", intoff, dwarfbuilder.LocationBlock(op.DW_OP_reg3))
dwb.TagClose()
bi := fakeBinaryInfo(t, dwb)
@ -173,6 +175,7 @@ func TestDwarfExprComposite(t *testing.T) {
regs.Rax = uint64(len(stringVal))
regs.Rdx = defaultCFA + 18
regs.Rcx = uint64(testCases["pair.k"])
regs.Rbx = uint64(testCases["n"])
scope := dwarfExprCheck(t, mem, dwarfRegisters(&regs), bi, testCases)

View File

@ -80,6 +80,13 @@ func cacheMemory(mem MemoryReadWriter, addr uintptr, size int) MemoryReadWriter
// including client code) assumes that addr == 0 is nil
const fakeAddress = 0xbeef0000
// compositeMemory represents a chunk of memory that is stored in CPU
// registers or non-contiguously.
//
// When optimizations are enabled the compiler will store some variables
// into registers and sometimes it will also store structs non-contiguously
// with some fields stored into CPU registers and other fields stored in
// memory.
type compositeMemory struct {
realmem MemoryReadWriter
regs op.DwarfRegisters

View File

@ -1897,13 +1897,19 @@ func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Varia
sort.Stable(&variablesByDepth{vars, depths})
}
// prefetch the whole chunk of memory relative to these variables
// Prefetch the whole chunk of memory relative to these variables.
// Variables that are not stored contiguously in memory (i.e. the ones that
// read from a compositeMemory) will be ignored.
minaddr := vars[0].Addr
var maxaddr uintptr
var size int64
for _, v := range vars {
if _, extloc := v.mem.(*compositeMemory); extloc {
continue
}
if v.Addr < minaddr {
minaddr = v.Addr
}
@ -1923,7 +1929,9 @@ func (scope *EvalScope) variablesByTag(tag dwarf.Tag, cfg *LoadConfig) ([]*Varia
mem := cacheMemory(vars[0].mem, minaddr, int(maxaddr-minaddr))
for _, v := range vars {
v.mem = mem
if _, extloc := v.mem.(*compositeMemory); !extloc {
v.mem = mem
}
}
}