Add call trace command
This commit is contained in:
parent
ef509eb308
commit
6bb932212c
@ -34,8 +34,6 @@ import (
|
||||
func init() {
|
||||
gob.Register(map[string]interface{}{})
|
||||
gob.Register([]interface{}{})
|
||||
gob.Register(&Room{})
|
||||
gob.Register(0)
|
||||
}
|
||||
|
||||
type RoomNameSource int
|
||||
|
@ -109,6 +109,7 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
|
||||
"invite": cmdInvite,
|
||||
"hprof": cmdHeapProfile,
|
||||
"cprof": cmdCPUProfile,
|
||||
"trace": cmdTrace,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -19,10 +19,12 @@ package ui
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
dbg "runtime/debug"
|
||||
"runtime/pprof"
|
||||
"runtime/trace"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@ -92,38 +94,37 @@ func cmdHeapProfile(cmd *Command) {
|
||||
}
|
||||
}
|
||||
|
||||
func cmdCPUProfile(cmd *Command) {
|
||||
func runTimedProfile(cmd *Command, start func(writer io.Writer) error, stop func(), task, file string) {
|
||||
if len(cmd.Args) == 0 {
|
||||
cmd.Reply("Usage: /cprof <seconds>")
|
||||
return
|
||||
}
|
||||
dur, err := strconv.Atoi(cmd.Args[0])
|
||||
if err != nil || dur < 0 {
|
||||
cmd.Reply("Usage: /cprof <seconds>")
|
||||
return
|
||||
}
|
||||
cpuProfile, err := os.Create("gomuks.cpu.prof")
|
||||
if err != nil {
|
||||
debug.Print("Failed to open gomuks.cpu.prof:", err)
|
||||
return
|
||||
}
|
||||
err = pprof.StartCPUProfile(cpuProfile)
|
||||
if err != nil {
|
||||
cmd.Reply("Usage: /%s <seconds>", cmd.Command)
|
||||
} else if dur, err := strconv.Atoi(cmd.Args[0]); err != nil || dur < 0 {
|
||||
cmd.Reply("Usage: /%s <seconds>", cmd.Command)
|
||||
} else if cpuProfile, err := os.Create(file); err != nil {
|
||||
debug.Printf("Failed to open %s: %v", file, err)
|
||||
} else if err = start(cpuProfile); err != nil {
|
||||
_ = cpuProfile.Close()
|
||||
debug.Print("CPU profile error:", err)
|
||||
return
|
||||
}
|
||||
cmd.Reply("Started CPU profiling for %d seconds", dur)
|
||||
go func() {
|
||||
time.Sleep(time.Duration(dur) * time.Second)
|
||||
pprof.StopCPUProfile()
|
||||
cmd.Reply("CPU profiling finished.")
|
||||
debug.Print(task, "error:", err)
|
||||
} else {
|
||||
cmd.Reply("Started %s for %d seconds", task, dur)
|
||||
go func() {
|
||||
time.Sleep(time.Duration(dur) * time.Second)
|
||||
stop()
|
||||
cmd.Reply("%s finished.", task)
|
||||
|
||||
err := cpuProfile.Close()
|
||||
if err != nil {
|
||||
debug.Print("Failed to close gomuks.cpu.prof:", err)
|
||||
}
|
||||
}()
|
||||
err := cpuProfile.Close()
|
||||
if err != nil {
|
||||
debug.Print("Failed to close gomuks.cpu.prof:", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func cmdCPUProfile(cmd *Command) {
|
||||
runTimedProfile(cmd, pprof.StartCPUProfile, pprof.StopCPUProfile, "CPU profiling", "gomuks.cpu.prof")
|
||||
}
|
||||
|
||||
func cmdTrace(cmd *Command) {
|
||||
runTimedProfile(cmd, trace.Start, trace.Stop, "Call tracing", "gomuks.trace")
|
||||
}
|
||||
|
||||
// TODO this command definitely belongs in a plugin once we have a plugin system.
|
||||
|
Loading…
Reference in New Issue
Block a user