Home | History | Annotate | Download | only in gc
      1 // Copyright 2015 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package gc
      6 
      7 import (
      8 	"os"
      9 	"runtime"
     10 	"runtime/pprof"
     11 )
     12 
     13 // Line returns n's position as a string. If n has been inlined,
     14 // it uses the outermost position where n has been inlined.
     15 func (n *Node) Line() string {
     16 	return linestr(n.Pos)
     17 }
     18 
     19 var atExitFuncs []func()
     20 
     21 func atExit(f func()) {
     22 	atExitFuncs = append(atExitFuncs, f)
     23 }
     24 
     25 func Exit(code int) {
     26 	for i := len(atExitFuncs) - 1; i >= 0; i-- {
     27 		f := atExitFuncs[i]
     28 		atExitFuncs = atExitFuncs[:i]
     29 		f()
     30 	}
     31 	os.Exit(code)
     32 }
     33 
     34 var (
     35 	blockprofile   string
     36 	cpuprofile     string
     37 	memprofile     string
     38 	memprofilerate int64
     39 	traceprofile   string
     40 	traceHandler   func(string)
     41 	mutexprofile   string
     42 )
     43 
     44 func startProfile() {
     45 	if cpuprofile != "" {
     46 		f, err := os.Create(cpuprofile)
     47 		if err != nil {
     48 			Fatalf("%v", err)
     49 		}
     50 		if err := pprof.StartCPUProfile(f); err != nil {
     51 			Fatalf("%v", err)
     52 		}
     53 		atExit(pprof.StopCPUProfile)
     54 	}
     55 	if memprofile != "" {
     56 		if memprofilerate != 0 {
     57 			runtime.MemProfileRate = int(memprofilerate)
     58 		}
     59 		f, err := os.Create(memprofile)
     60 		if err != nil {
     61 			Fatalf("%v", err)
     62 		}
     63 		atExit(func() {
     64 			// Profile all outstanding allocations.
     65 			runtime.GC()
     66 			// compilebench parses the memory profile to extract memstats,
     67 			// which are only written in the legacy pprof format.
     68 			// See golang.org/issue/18641 and runtime/pprof/pprof.go:writeHeap.
     69 			const writeLegacyFormat = 1
     70 			if err := pprof.Lookup("heap").WriteTo(f, writeLegacyFormat); err != nil {
     71 				Fatalf("%v", err)
     72 			}
     73 		})
     74 	} else {
     75 		// Not doing memory profiling; disable it entirely.
     76 		runtime.MemProfileRate = 0
     77 	}
     78 	if blockprofile != "" {
     79 		f, err := os.Create(blockprofile)
     80 		if err != nil {
     81 			Fatalf("%v", err)
     82 		}
     83 		runtime.SetBlockProfileRate(1)
     84 		atExit(func() {
     85 			pprof.Lookup("block").WriteTo(f, 0)
     86 			f.Close()
     87 		})
     88 	}
     89 	if mutexprofile != "" {
     90 		f, err := os.Create(mutexprofile)
     91 		if err != nil {
     92 			Fatalf("%v", err)
     93 		}
     94 		startMutexProfiling()
     95 		atExit(func() {
     96 			pprof.Lookup("mutex").WriteTo(f, 0)
     97 			f.Close()
     98 		})
     99 	}
    100 	if traceprofile != "" && traceHandler != nil {
    101 		traceHandler(traceprofile)
    102 	}
    103 }
    104