proc: move AllGCache to a common struct

Add a new method "Common" to proc.Process that returns a pointer to a
struct that pkg/proc can use to store its things, independently of the
backend.

This is used here to replace the AllGCache typecasts, it will also be
used to store the return values of the stepout breakpoint and the state
for injected function calls.
This commit is contained in:
aarzilli
2018-05-10 21:25:59 +02:00
committed by Alessandro Arzilli
parent d04c60e0b9
commit f38a2816d1
6 changed files with 28 additions and 32 deletions

View File

@ -147,7 +147,7 @@ type Process struct {
breakpoints proc.BreakpointMap
currentThread *Thread
selectedGoroutine *proc.G
allGCache []*proc.G
common proc.CommonProcess
}
type Thread struct {
@ -298,8 +298,8 @@ func (p *Process) Exited() bool {
return false
}
func (p *Process) AllGCache() *[]*proc.G {
return &p.allGCache
func (p *Process) Common() *proc.CommonProcess {
return &p.common
}
func (p *Process) Pid() int {

View File

@ -121,7 +121,7 @@ type Process struct {
process *os.Process
waitChan chan *os.ProcessState
allGCache []*proc.G
common proc.CommonProcess
}
// Thread is a thread.
@ -584,8 +584,8 @@ func (p *Process) CurrentThread() proc.Thread {
return p.currentThread
}
func (p *Process) AllGCache() *[]*proc.G {
return &p.allGCache
func (p *Process) Common() *proc.CommonProcess {
return &p.common
}
func (p *Process) SelectedGoroutine() *proc.G {
@ -615,7 +615,7 @@ func (p *Process) ContinueOnce() (proc.Thread, error) {
}
}
p.allGCache = nil
p.common.ClearAllGCache()
for _, th := range p.threads {
th.clearBreakpointState()
}
@ -710,7 +710,7 @@ func (p *Process) StepInstruction() error {
}
thread = p.selectedGoroutine.Thread.(*Thread)
}
p.allGCache = nil
p.common.ClearAllGCache()
if p.exited {
return &proc.ProcessExitedError{Pid: p.conn.pid}
}
@ -819,7 +819,7 @@ func (p *Process) Restart(pos string) error {
p.exited = false
p.allGCache = nil
p.common.ClearAllGCache()
for _, th := range p.threads {
th.clearBreakpointState()
}

View File

@ -62,6 +62,8 @@ type Info interface {
ResumeNotify(chan<- struct{})
Exited() bool
BinInfo() *BinaryInfo
// Common returns a struct with fields common to all backends
Common() *CommonProcess
ThreadInfo
GoroutineInfo
@ -100,3 +102,11 @@ type BreakpointManipulation interface {
ClearBreakpoint(addr uint64) (*Breakpoint, error)
ClearInternalBreakpoints() error
}
type CommonProcess struct {
allGCache []*G
}
func (p *CommonProcess) ClearAllGCache() {
p.allGCache = nil
}

View File

@ -29,7 +29,7 @@ type Process struct {
// Normally selectedGoroutine is currentThread.GetG, it will not be only if SwitchGoroutine is called with a goroutine that isn't attached to a thread
selectedGoroutine *proc.G
allGCache []*proc.G
common proc.CommonProcess
os *OSProcessDetails
firstStart bool
stopMu sync.Mutex
@ -230,7 +230,7 @@ func (dbp *Process) ContinueOnce() (proc.Thread, error) {
return nil, err
}
dbp.allGCache = nil
dbp.common.ClearAllGCache()
for _, th := range dbp.threads {
th.CurrentBreakpoint.Clear()
}
@ -266,7 +266,7 @@ func (dbp *Process) StepInstruction() (err error) {
}
thread = dbp.selectedGoroutine.Thread.(*Thread)
}
dbp.allGCache = nil
dbp.common.ClearAllGCache()
if dbp.exited {
return &proc.ProcessExitedError{Pid: dbp.Pid()}
}
@ -397,6 +397,6 @@ func (dbp *Process) writeSoftwareBreakpoint(thread *Thread, addr uint64) error {
return err
}
func (dbp *Process) AllGCache() *[]*proc.G {
return &dbp.allGCache
func (dbp *Process) Common() *proc.CommonProcess {
return &dbp.common
}

View File

@ -373,22 +373,14 @@ func StepOut(dbp Process) error {
return Continue(dbp)
}
// If the argument of GoroutinesInfo implements AllGCache GoroutinesInfo
// will use the pointer returned by AllGCache as a cache.
type AllGCache interface {
AllGCache() *[]*G
}
// GoroutinesInfo returns an array of G structures representing the information
// Delve cares about from the internal runtime G structure.
func GoroutinesInfo(dbp Process) ([]*G, error) {
if dbp.Exited() {
return nil, &ProcessExitedError{Pid: dbp.Pid()}
}
if dbp, ok := dbp.(AllGCache); ok {
if allGCache := dbp.AllGCache(); *allGCache != nil {
return *allGCache, nil
}
if dbp.Common().allGCache != nil {
return dbp.Common().allGCache, nil
}
var (
@ -458,10 +450,7 @@ func GoroutinesInfo(dbp Process) ([]*G, error) {
allg = append(allg, g)
}
}
if dbp, ok := dbp.(AllGCache); ok {
allGCache := dbp.AllGCache()
*allGCache = allg
}
dbp.Common().allGCache = allg
return allg, nil
}

View File

@ -1515,10 +1515,7 @@ func BenchmarkGoroutinesInfo(b *testing.B) {
withTestProcess("testvariables2", b, func(p proc.Process, fixture protest.Fixture) {
assertNoError(proc.Continue(p), b, "Continue()")
for i := 0; i < b.N; i++ {
if p, ok := p.(proc.AllGCache); ok {
allgcache := p.AllGCache()
*allgcache = nil
}
p.Common().ClearAllGCache()
_, err := proc.GoroutinesInfo(p)
assertNoError(err, b, "GoroutinesInfo")
}