Skip to content

Commit

Permalink
proc: disable caching for variables with an extended location
Browse files Browse the repository at this point in the history
Our current frame caching strategy doesn't handle extended locations
expressions correctly, disable it on variables that don't have a simple
address.
  • Loading branch information
aarzilli authored and derekparker committed Jan 31, 2018
1 parent 03139e8 commit 62fe792
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
3 changes: 3 additions & 0 deletions pkg/proc/dwarf_expr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand All @@ -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)

Expand Down
7 changes: 7 additions & 0 deletions pkg/proc/mem.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 10 additions & 2 deletions pkg/proc/variables.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand All @@ -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
}
}
}

Expand Down

0 comments on commit 62fe792

Please sign in to comment.