// Copyright 2015 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package gc import ( "os" "runtime" "runtime/pprof" "cmd/compile/internal/base" ) var ( memprofilerate int64 traceHandler func(string) ) func startProfile() { if base.Flag.CPUProfile != "" { f, err := os.Create(base.Flag.CPUProfile) if err != nil { base.Fatalf("%v", err) } if err := pprof.StartCPUProfile(f); err != nil { base.Fatalf("%v", err) } base.AtExit(pprof.StopCPUProfile) } if base.Flag.MemProfile != "" { if memprofilerate != 0 { runtime.MemProfileRate = int(memprofilerate) } f, err := os.Create(base.Flag.MemProfile) if err != nil { base.Fatalf("%v", err) } base.AtExit(func() { // Profile all outstanding allocations. runtime.GC() // compilebench parses the memory profile to extract memstats, // which are only written in the legacy pprof format. // See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap. const writeLegacyFormat = 1 if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil { base.Fatalf("%v", err) } }) } else { // Not doing memory profiling; disable it entirely. runtime.MemProfileRate = 0 } if base.Flag.BlockProfile != "" { f, err := os.Create(base.Flag.BlockProfile) if err != nil { base.Fatalf("%v", err) } runtime.SetBlockProfileRate(1) base.AtExit(func() { pprof.Lookup("block").WriteTo(f, 0) f.Close() }) } if base.Flag.MutexProfile != "" { f, err := os.Create(base.Flag.MutexProfile) if err != nil { base.Fatalf("%v", err) } startMutexProfiling() base.AtExit(func() { pprof.Lookup("mutex").WriteTo(f, 0) f.Close() }) } if base.Flag.TraceProfile != "" && traceHandler != nil { traceHandler(base.Flag.TraceProfile) } }