diff options
Diffstat (limited to 'pkg/sentry/control')
-rw-r--r-- | pkg/sentry/control/pprof.go | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/pkg/sentry/control/pprof.go b/pkg/sentry/control/pprof.go index 94ed149f2..d63916600 100644 --- a/pkg/sentry/control/pprof.go +++ b/pkg/sentry/control/pprof.go @@ -18,6 +18,7 @@ import ( "errors" "runtime" "runtime/pprof" + "runtime/trace" "sync" "gvisor.googlesource.com/gvisor/pkg/fd" @@ -52,6 +53,9 @@ type Profile struct { // cpuFile is the current CPU profile output file. cpuFile *fd.FD + + // traceFile is the current execution trace output file. + traceFile *fd.FD } // StartCPUProfile is an RPC stub which starts recording the CPU profile in a @@ -122,3 +126,43 @@ func (p *Profile) Goroutine(o *ProfileOpts, _ *struct{}) error { } return nil } + +// StartTrace is an RPC stub which starts collection of an execution trace. +func (p *Profile) StartTrace(o *ProfileOpts, _ *struct{}) error { + if len(o.FilePayload.Files) < 1 { + return errNoOutput + } + + output, err := fd.NewFromFile(o.FilePayload.Files[0]) + if err != nil { + return err + } + + p.mu.Lock() + defer p.mu.Unlock() + + // Returns an error if profiling is already started. + if err := trace.Start(output); err != nil { + output.Close() + return err + } + + p.traceFile = output + return nil +} + +// StopTrace is an RPC stub which stops collection of an ongoing execution +// trace and flushes the trace data. It takes no argument. +func (p *Profile) StopTrace(_, _ *struct{}) error { + p.mu.Lock() + defer p.mu.Unlock() + + if p.traceFile == nil { + return errors.New("Execution tracing not start") + } + + trace.Stop() + p.traceFile.Close() + p.traceFile = nil + return nil +} |