proc: move g.stackhi/g.stacklo to a struct

Mirroring the way this is implemented in the Go runtime and introducing
a type that will be useful to support the call injection changes in Go
1.15
This commit is contained in:
aarzilli 2020-04-22 16:39:06 +02:00 committed by Derek Parker
parent bb2525a7d5
commit cf37512aed
4 changed files with 20 additions and 17 deletions

@ -436,8 +436,8 @@ func (rbpi *returnBreakpointInfo) Collect(thread Thread) []*Variable {
return nil
}
oldFrameOffset := rbpi.frameOffset + int64(g.stackhi)
oldSP := uint64(rbpi.spOffset + int64(g.stackhi))
oldFrameOffset := rbpi.frameOffset + int64(g.stack.hi)
oldSP := uint64(rbpi.spOffset + int64(g.stack.hi))
err = fakeFunctionEntryScope(scope, rbpi.fn, oldFrameOffset, oldSP)
if err != nil {
return returnInfoError("could not read function entry", err, thread)

@ -257,7 +257,7 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
return nil, err
}
regs = regs.Copy()
if regs.SP()-256 <= scope.g.stacklo {
if regs.SP()-256 <= scope.g.stack.lo {
return nil, errNotEnoughStack
}
_, err = regs.Get(int(x86asm.RAX))
@ -285,9 +285,9 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
fncallLog("function call initiated %v frame size %d", fncall.fn, fncall.argFrameSize)
spoff := int64(scope.Regs.Uint64Val(scope.Regs.SPRegNum)) - int64(scope.g.stackhi)
bpoff := int64(scope.Regs.Uint64Val(scope.Regs.BPRegNum)) - int64(scope.g.stackhi)
fboff := scope.Regs.FrameBase - int64(scope.g.stackhi)
spoff := int64(scope.Regs.Uint64Val(scope.Regs.SPRegNum)) - int64(scope.g.stack.hi)
bpoff := int64(scope.Regs.Uint64Val(scope.Regs.BPRegNum)) - int64(scope.g.stack.hi)
fboff := scope.Regs.FrameBase - int64(scope.g.stack.hi)
for {
scope.g = scope.callCtx.doContinue()
@ -303,10 +303,10 @@ func evalFunctionCall(scope *EvalScope, node *ast.CallExpr) (*Variable, error) {
}
}
scope.Regs.Regs[scope.Regs.SPRegNum].Uint64Val = uint64(spoff + int64(scope.g.stackhi))
scope.Regs.Regs[scope.Regs.BPRegNum].Uint64Val = uint64(bpoff + int64(scope.g.stackhi))
scope.Regs.FrameBase = fboff + int64(scope.g.stackhi)
scope.Regs.CFA = scope.frameOffset + int64(scope.g.stackhi)
scope.Regs.Regs[scope.Regs.SPRegNum].Uint64Val = uint64(spoff + int64(scope.g.stack.hi))
scope.Regs.Regs[scope.Regs.BPRegNum].Uint64Val = uint64(bpoff + int64(scope.g.stack.hi))
scope.Regs.FrameBase = fboff + int64(scope.g.stack.hi)
scope.Regs.CFA = scope.frameOffset + int64(scope.g.stack.hi)
finished := funcCallStep(scope, &fncall)
if finished {
@ -635,7 +635,7 @@ func escapeCheck(v *Variable, name string, g *G) error {
}
func escapeCheckPointer(addr uintptr, name string, g *G) error {
if uint64(addr) >= g.stacklo && uint64(addr) < g.stackhi {
if uint64(addr) >= g.stack.lo && uint64(addr) < g.stack.hi {
return fmt.Errorf("stack object passed to escaping pointer: %s", name)
}
return nil

@ -122,13 +122,13 @@ func (g *G) stackIterator(opts StacktraceOptions) (*stackIterator, error) {
return newStackIterator(
bi, g.Thread,
bi.Arch.RegistersToDwarfRegisters(so.StaticBase, regs),
g.stackhi, stkbar, g.stkbarPos, g, opts), nil
g.stack.hi, stkbar, g.stkbarPos, g, opts), nil
}
so := g.variable.bi.PCToImage(g.PC)
return newStackIterator(
bi, g.variable.mem,
bi.Arch.addrAndStackRegsToDwarfRegisters(so.StaticBase, g.PC, g.SP, g.BP, g.LR),
g.stackhi, stkbar, g.stkbarPos, g, opts), nil
g.stack.hi, stkbar, g.stkbarPos, g, opts), nil
}
type StacktraceOptions uint16

@ -195,8 +195,7 @@ type G struct {
Status uint64
stkbarVar *Variable // stkbar field of g struct
stkbarPos int // stkbarPos field of g struct
stackhi uint64 // value of stack.hi
stacklo uint64 // value of stack.lo
stack stack // value of stack
SystemStack bool // SystemStack is true if this goroutine is currently executing on a system stack.
@ -213,6 +212,11 @@ type G struct {
labels *map[string]string // G's pprof labels, computed on demand in Labels() method
}
// stack represents a stack span in the target process.
type stack struct {
hi, lo uint64
}
// GetG returns information on the G (goroutine) that is executing on this thread.
//
// The G structure for a thread is stored in thread local storage. Here we simply
@ -862,8 +866,7 @@ func (v *Variable) parseG() (*G, error) {
variable: v,
stkbarVar: stkbarVar,
stkbarPos: int(stkbarPos),
stackhi: stackhi,
stacklo: stacklo,
stack: stack{hi: stackhi, lo: stacklo},
}
return g, nil
}