mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: Profile goroutines holding contended mutexes.
runtime.SetMutexProfileFraction(n int) will capture 1/n-th of stack
traces of goroutines holding contended mutexes if n > 0. From runtime/pprof,
pprot.Lookup("mutex").WriteTo writes the accumulated
stack traces to w (in essentially the same format that blocking
profiling uses).
Change-Id: Ie0b54fa4226853d99aa42c14cb529ae586a8335a
Reviewed-on: https://go-review.googlesource.com/29650
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
b679665a18
commit
ca922b6d36
15 changed files with 286 additions and 39 deletions
|
|
@ -233,19 +233,21 @@ var (
|
|||
outputDir = flag.String("test.outputdir", "", "write profiles to `dir`")
|
||||
|
||||
// Report as tests are run; default is silent for success.
|
||||
chatty = flag.Bool("test.v", false, "verbose: print additional output")
|
||||
count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
|
||||
coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
|
||||
match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
|
||||
memProfile = flag.String("test.memprofile", "", "write a memory profile to `file`")
|
||||
memProfileRate = flag.Int("test.memprofilerate", 0, "set memory profiling `rate` (see runtime.MemProfileRate)")
|
||||
cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
|
||||
blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to `file`")
|
||||
blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
|
||||
traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
|
||||
timeout = flag.Duration("test.timeout", 0, "fail test binary execution after duration `d` (0 means unlimited)")
|
||||
cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
|
||||
parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
|
||||
chatty = flag.Bool("test.v", false, "verbose: print additional output")
|
||||
count = flag.Uint("test.count", 1, "run tests and benchmarks `n` times")
|
||||
coverProfile = flag.String("test.coverprofile", "", "write a coverage profile to `file`")
|
||||
match = flag.String("test.run", "", "run only tests and examples matching `regexp`")
|
||||
memProfile = flag.String("test.memprofile", "", "write a memory profile to `file`")
|
||||
memProfileRate = flag.Int("test.memprofilerate", 0, "set memory profiling `rate` (see runtime.MemProfileRate)")
|
||||
cpuProfile = flag.String("test.cpuprofile", "", "write a cpu profile to `file`")
|
||||
blockProfile = flag.String("test.blockprofile", "", "write a goroutine blocking profile to `file`")
|
||||
blockProfileRate = flag.Int("test.blockprofilerate", 1, "set blocking profile `rate` (see runtime.SetBlockProfileRate)")
|
||||
mutexProfile = flag.String("test.mutexprofile", "", "write a mutex contention profile to the named file after execution")
|
||||
mutexProfileFraction = flag.Int("test.mutexprofilefraction", 1, "if >= 0, calls runtime.SetMutexProfileFraction()")
|
||||
traceFile = flag.String("test.trace", "", "write an execution trace to `file`")
|
||||
timeout = flag.Duration("test.timeout", 0, "fail test binary execution after duration `d` (0 means unlimited)")
|
||||
cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with")
|
||||
parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel")
|
||||
|
||||
haveExamples bool // are there examples?
|
||||
|
||||
|
|
@ -874,6 +876,9 @@ func before() {
|
|||
if *blockProfile != "" && *blockProfileRate >= 0 {
|
||||
runtime.SetBlockProfileRate(*blockProfileRate)
|
||||
}
|
||||
if *mutexProfile != "" && *mutexProfileFraction >= 0 {
|
||||
runtime.SetMutexProfileFraction(*mutexProfileFraction)
|
||||
}
|
||||
if *coverProfile != "" && cover.Mode == "" {
|
||||
fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n")
|
||||
os.Exit(2)
|
||||
|
|
@ -913,6 +918,18 @@ func after() {
|
|||
}
|
||||
f.Close()
|
||||
}
|
||||
if *mutexProfile != "" && *mutexProfileFraction >= 0 {
|
||||
f, err := os.Create(toOutputDir(*mutexProfile))
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "testing: %s\n", err)
|
||||
os.Exit(2)
|
||||
}
|
||||
if err = pprof.Lookup("mutex").WriteTo(f, 0); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *blockProfile, err)
|
||||
os.Exit(2)
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
if cover.Mode != "" {
|
||||
coverReport()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue