1
2
3
4
5 package gc
6
7 import (
8 "net/url"
9 "os"
10 "path/filepath"
11 "runtime"
12 "runtime/pprof"
13 tracepkg "runtime/trace"
14 "strings"
15
16 "cmd/compile/internal/base"
17 )
18
19 func profileName(fn, suffix string) string {
20 if strings.HasSuffix(fn, string(os.PathSeparator)) {
21 err := os.MkdirAll(fn, 0755)
22 if err != nil {
23 base.Fatalf("%v", err)
24 }
25 }
26 if fi, statErr := os.Stat(fn); statErr == nil && fi.IsDir() {
27 fn = filepath.Join(fn, url.PathEscape(base.Ctxt.Pkgpath)+suffix)
28 }
29 return fn
30 }
31
32 func startProfile() {
33 if base.Flag.CPUProfile != "" {
34 fn := profileName(base.Flag.CPUProfile, ".cpuprof")
35 f, err := os.Create(fn)
36 if err != nil {
37 base.Fatalf("%v", err)
38 }
39 if err := pprof.StartCPUProfile(f); err != nil {
40 base.Fatalf("%v", err)
41 }
42 base.AtExit(func() {
43 pprof.StopCPUProfile()
44 if err = f.Close(); err != nil {
45 base.Fatalf("error closing cpu profile: %v", err)
46 }
47 })
48 }
49 if base.Flag.MemProfile != "" {
50 if base.Flag.MemProfileRate != 0 {
51 runtime.MemProfileRate = base.Flag.MemProfileRate
52 }
53 const (
54 gzipFormat = 0
55 textFormat = 1
56 )
57
58
59
60
61 var format = textFormat
62 fn := base.Flag.MemProfile
63 if strings.HasSuffix(fn, string(os.PathSeparator)) {
64 err := os.MkdirAll(fn, 0755)
65 if err != nil {
66 base.Fatalf("%v", err)
67 }
68 }
69 if fi, statErr := os.Stat(fn); statErr == nil && fi.IsDir() {
70 fn = filepath.Join(fn, url.PathEscape(base.Ctxt.Pkgpath)+".memprof")
71 format = gzipFormat
72 }
73
74 f, err := os.Create(fn)
75
76 if err != nil {
77 base.Fatalf("%v", err)
78 }
79 base.AtExit(func() {
80
81 runtime.GC()
82 if err := pprof.Lookup("heap").WriteTo(f, format); err != nil {
83 base.Fatalf("%v", err)
84 }
85 if err = f.Close(); err != nil {
86 base.Fatalf("error closing memory profile: %v", err)
87 }
88 })
89 } else {
90
91 runtime.MemProfileRate = 0
92 }
93 if base.Flag.BlockProfile != "" {
94 f, err := os.Create(profileName(base.Flag.BlockProfile, ".blockprof"))
95 if err != nil {
96 base.Fatalf("%v", err)
97 }
98 runtime.SetBlockProfileRate(1)
99 base.AtExit(func() {
100 pprof.Lookup("block").WriteTo(f, 0)
101 f.Close()
102 })
103 }
104 if base.Flag.MutexProfile != "" {
105 f, err := os.Create(profileName(base.Flag.MutexProfile, ".mutexprof"))
106 if err != nil {
107 base.Fatalf("%v", err)
108 }
109 runtime.SetMutexProfileFraction(1)
110 base.AtExit(func() {
111 pprof.Lookup("mutex").WriteTo(f, 0)
112 f.Close()
113 })
114 }
115 if base.Flag.TraceProfile != "" {
116 f, err := os.Create(profileName(base.Flag.TraceProfile, ".trace"))
117 if err != nil {
118 base.Fatalf("%v", err)
119 }
120 if err := tracepkg.Start(f); err != nil {
121 base.Fatalf("%v", err)
122 }
123 base.AtExit(func() {
124 tracepkg.Stop()
125 if err = f.Close(); err != nil {
126 base.Fatalf("error closing trace profile: %v", err)
127 }
128 })
129 }
130 }
131
View as plain text