summaryrefslogtreecommitdiffhomepage
path: root/pkg/sentry/control
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/sentry/control')
-rw-r--r--pkg/sentry/control/pprof.go44
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
+}