From 29a058ee7e18bf88613f69770ae08de4964ba792 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Tue, 16 Jul 2019 22:12:16 +0200 Subject: [PATCH] proc: flag variables that have a 'fake' address (#1619) Add variables flag to mark variables that are allocated on a register (and have no address) and variables that we read as result of a function call (and are allocated on a stack that no longer exists when we show them to the user). --- pkg/proc/fncall.go | 9 ++++----- pkg/proc/variables.go | 9 +++++++++ service/api/types.go | 7 +++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/pkg/proc/fncall.go b/pkg/proc/fncall.go index 5ebcd174..f6cab15b 100644 --- a/pkg/proc/fncall.go +++ b/pkg/proc/fncall.go @@ -746,6 +746,9 @@ func funcCallStep(callScope *EvalScope, fncall *functionCallState) bool { } loadValues(fncall.retvars, callScope.callCtx.retLoadCfg) + for _, v := range fncall.retvars { + v.Flags |= VariableFakeAddress + } case debugCallAXReadPanic: // read panic value from stack @@ -755,11 +758,6 @@ func funcCallStep(callScope *EvalScope, fncall *functionCallState) bool { break } fncall.panicvar.Name = "~panic" - fncall.panicvar.loadValue(callScope.callCtx.retLoadCfg) - if fncall.panicvar.Unreadable != nil { - fncall.err = fmt.Errorf("could not get panic: %v", fncall.panicvar.Unreadable) - break - } default: // Got an unknown AX value, this is probably bad but the safest thing @@ -785,6 +783,7 @@ func readTopstackVariable(thread Thread, regs Registers, typename string, loadCf if v.Unreadable != nil { return nil, v.Unreadable } + v.Flags |= VariableFakeAddress return v, nil } diff --git a/pkg/proc/variables.go b/pkg/proc/variables.go index 7ea7357c..9c01038a 100644 --- a/pkg/proc/variables.go +++ b/pkg/proc/variables.go @@ -71,6 +71,12 @@ const ( VariableArgument // VariableReturnArgument means this variable is a function return value VariableReturnArgument + // VariableFakeAddress means the address of this variable is either fake + // (i.e. the variable is partially or completely stored in a CPU register + // and doesn't have a real address) or possibly no longer availabe (because + // the variable is the return value of a function call and allocated on a + // frame that no longer exists) + VariableFakeAddress ) // Variable represents a variable. It contains the address, name, @@ -1051,6 +1057,9 @@ func (scope *EvalScope) extractVarInfoFromEntry(varEntry *dwarf.Entry) (*Variabl } v := scope.newVariable(n, uintptr(addr), t, mem) + if pieces != nil { + v.Flags |= VariableFakeAddress + } v.LocationExpr = descr v.DeclLine, _ = entry.Val(dwarf.AttrDeclLine).(int64) if err != nil { diff --git a/service/api/types.go b/service/api/types.go index b2707595..95e55b94 100644 --- a/service/api/types.go +++ b/service/api/types.go @@ -214,6 +214,13 @@ const ( // VariableReturnArgument means this variable is a function return value VariableReturnArgument + + // VariableFakeAddress means the address of this variable is either fake + // (i.e. the variable is partially or completely stored in a CPU register + // and doesn't have a real address) or possibly no longer availabe (because + // the variable is the return value of a function call and allocated on a + // frame that no longer exists) + VariableFakeAddress ) // Variable describes a variable.