Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / runtime / pprof / pprof.go
1 // Copyright 2010 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 pprof writes runtime profiling data in the format expected
6 // by the pprof visualization tool.
7 // For more information about pprof, see
8 // http://code.google.com/p/google-perftools/.
9 package pprof
10
11 import (
12         "bufio"
13         "bytes"
14         "fmt"
15         "io"
16         "runtime"
17         "sort"
18         "strings"
19         "sync"
20         "text/tabwriter"
21 )
22
23 // BUG(rsc): A bug in the OS X Snow Leopard 64-bit kernel prevents
24 // CPU profiling from giving accurate results on that system.
25
26 // A Profile is a collection of stack traces showing the call sequences
27 // that led to instances of a particular event, such as allocation.
28 // Packages can create and maintain their own profiles; the most common
29 // use is for tracking resources that must be explicitly closed, such as files
30 // or network connections.
31 //
32 // A Profile's methods can be called from multiple goroutines simultaneously.
33 //
34 // Each Profile has a unique name.  A few profiles are predefined:
35 //
36 //      goroutine    - stack traces of all current goroutines
37 //      heap         - a sampling of all heap allocations
38 //      threadcreate - stack traces that led to the creation of new OS threads
39 //      block        - stack traces that led to blocking on synchronization primitives
40 //
41 // These predefined profiles maintain themselves and panic on an explicit
42 // Add or Remove method call.
43 //
44 // The CPU profile is not available as a Profile.  It has a special API,
45 // the StartCPUProfile and StopCPUProfile functions, because it streams
46 // output to a writer during profiling.
47 //
48 type Profile struct {
49         name  string
50         mu    sync.Mutex
51         m     map[interface{}][]uintptr
52         count func() int
53         write func(io.Writer, int) error
54 }
55
56 // profiles records all registered profiles.
57 var profiles struct {
58         mu sync.Mutex
59         m  map[string]*Profile
60 }
61
62 var goroutineProfile = &Profile{
63         name:  "goroutine",
64         count: countGoroutine,
65         write: writeGoroutine,
66 }
67
68 var threadcreateProfile = &Profile{
69         name:  "threadcreate",
70         count: countThreadCreate,
71         write: writeThreadCreate,
72 }
73
74 var heapProfile = &Profile{
75         name:  "heap",
76         count: countHeap,
77         write: writeHeap,
78 }
79
80 var blockProfile = &Profile{
81         name:  "block",
82         count: countBlock,
83         write: writeBlock,
84 }
85
86 func lockProfiles() {
87         profiles.mu.Lock()
88         if profiles.m == nil {
89                 // Initial built-in profiles.
90                 profiles.m = map[string]*Profile{
91                         "goroutine":    goroutineProfile,
92                         "threadcreate": threadcreateProfile,
93                         "heap":         heapProfile,
94                         "block":        blockProfile,
95                 }
96         }
97 }
98
99 func unlockProfiles() {
100         profiles.mu.Unlock()
101 }
102
103 // NewProfile creates a new profile with the given name.
104 // If a profile with that name already exists, NewProfile panics.
105 // The convention is to use a 'import/path.' prefix to create
106 // separate name spaces for each package.
107 func NewProfile(name string) *Profile {
108         lockProfiles()
109         defer unlockProfiles()
110         if name == "" {
111                 panic("pprof: NewProfile with empty name")
112         }
113         if profiles.m[name] != nil {
114                 panic("pprof: NewProfile name already in use: " + name)
115         }
116         p := &Profile{
117                 name: name,
118                 m:    map[interface{}][]uintptr{},
119         }
120         profiles.m[name] = p
121         return p
122 }
123
124 // Lookup returns the profile with the given name, or nil if no such profile exists.
125 func Lookup(name string) *Profile {
126         lockProfiles()
127         defer unlockProfiles()
128         return profiles.m[name]
129 }
130
131 // Profiles returns a slice of all the known profiles, sorted by name.
132 func Profiles() []*Profile {
133         lockProfiles()
134         defer unlockProfiles()
135
136         var all []*Profile
137         for _, p := range profiles.m {
138                 all = append(all, p)
139         }
140
141         sort.Sort(byName(all))
142         return all
143 }
144
145 type byName []*Profile
146
147 func (x byName) Len() int           { return len(x) }
148 func (x byName) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
149 func (x byName) Less(i, j int) bool { return x[i].name < x[j].name }
150
151 // Name returns this profile's name, which can be passed to Lookup to reobtain the profile.
152 func (p *Profile) Name() string {
153         return p.name
154 }
155
156 // Count returns the number of execution stacks currently in the profile.
157 func (p *Profile) Count() int {
158         p.mu.Lock()
159         defer p.mu.Unlock()
160         if p.count != nil {
161                 return p.count()
162         }
163         return len(p.m)
164 }
165
166 // Add adds the current execution stack to the profile, associated with value.
167 // Add stores value in an internal map, so value must be suitable for use as
168 // a map key and will not be garbage collected until the corresponding
169 // call to Remove.  Add panics if the profile already contains a stack for value.
170 //
171 // The skip parameter has the same meaning as runtime.Caller's skip
172 // and controls where the stack trace begins.  Passing skip=0 begins the
173 // trace in the function calling Add.  For example, given this
174 // execution stack:
175 //
176 //      Add
177 //      called from rpc.NewClient
178 //      called from mypkg.Run
179 //      called from main.main
180 //
181 // Passing skip=0 begins the stack trace at the call to Add inside rpc.NewClient.
182 // Passing skip=1 begins the stack trace at the call to NewClient inside mypkg.Run.
183 //
184 func (p *Profile) Add(value interface{}, skip int) {
185         if p.name == "" {
186                 panic("pprof: use of uninitialized Profile")
187         }
188         if p.write != nil {
189                 panic("pprof: Add called on built-in Profile " + p.name)
190         }
191
192         stk := make([]uintptr, 32)
193         n := runtime.Callers(skip+1, stk[:])
194
195         p.mu.Lock()
196         defer p.mu.Unlock()
197         if p.m[value] != nil {
198                 panic("pprof: Profile.Add of duplicate value")
199         }
200         p.m[value] = stk[:n]
201 }
202
203 // Remove removes the execution stack associated with value from the profile.
204 // It is a no-op if the value is not in the profile.
205 func (p *Profile) Remove(value interface{}) {
206         p.mu.Lock()
207         defer p.mu.Unlock()
208         delete(p.m, value)
209 }
210
211 // WriteTo writes a pprof-formatted snapshot of the profile to w.
212 // If a write to w returns an error, WriteTo returns that error.
213 // Otherwise, WriteTo returns nil.
214 //
215 // The debug parameter enables additional output.
216 // Passing debug=0 prints only the hexadecimal addresses that pprof needs.
217 // Passing debug=1 adds comments translating addresses to function names
218 // and line numbers, so that a programmer can read the profile without tools.
219 //
220 // The predefined profiles may assign meaning to other debug values;
221 // for example, when printing the "goroutine" profile, debug=2 means to
222 // print the goroutine stacks in the same form that a Go program uses
223 // when dying due to an unrecovered panic.
224 func (p *Profile) WriteTo(w io.Writer, debug int) error {
225         if p.name == "" {
226                 panic("pprof: use of zero Profile")
227         }
228         if p.write != nil {
229                 return p.write(w, debug)
230         }
231
232         // Obtain consistent snapshot under lock; then process without lock.
233         var all [][]uintptr
234         p.mu.Lock()
235         for _, stk := range p.m {
236                 all = append(all, stk)
237         }
238         p.mu.Unlock()
239
240         // Map order is non-deterministic; make output deterministic.
241         sort.Sort(stackProfile(all))
242
243         return printCountProfile(w, debug, p.name, stackProfile(all))
244 }
245
246 type stackProfile [][]uintptr
247
248 func (x stackProfile) Len() int              { return len(x) }
249 func (x stackProfile) Stack(i int) []uintptr { return x[i] }
250 func (x stackProfile) Swap(i, j int)         { x[i], x[j] = x[j], x[i] }
251 func (x stackProfile) Less(i, j int) bool {
252         t, u := x[i], x[j]
253         for k := 0; k < len(t) && k < len(u); k++ {
254                 if t[k] != u[k] {
255                         return t[k] < u[k]
256                 }
257         }
258         return len(t) < len(u)
259 }
260
261 // A countProfile is a set of stack traces to be printed as counts
262 // grouped by stack trace.  There are multiple implementations:
263 // all that matters is that we can find out how many traces there are
264 // and obtain each trace in turn.
265 type countProfile interface {
266         Len() int
267         Stack(i int) []uintptr
268 }
269
270 // printCountProfile prints a countProfile at the specified debug level.
271 func printCountProfile(w io.Writer, debug int, name string, p countProfile) error {
272         b := bufio.NewWriter(w)
273         var tw *tabwriter.Writer
274         w = b
275         if debug > 0 {
276                 tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
277                 w = tw
278         }
279
280         fmt.Fprintf(w, "%s profile: total %d\n", name, p.Len())
281
282         // Build count of each stack.
283         var buf bytes.Buffer
284         key := func(stk []uintptr) string {
285                 buf.Reset()
286                 fmt.Fprintf(&buf, "@")
287                 for _, pc := range stk {
288                         fmt.Fprintf(&buf, " %#x", pc)
289                 }
290                 return buf.String()
291         }
292         m := map[string]int{}
293         n := p.Len()
294         for i := 0; i < n; i++ {
295                 m[key(p.Stack(i))]++
296         }
297
298         // Print stacks, listing count on first occurrence of a unique stack.
299         for i := 0; i < n; i++ {
300                 stk := p.Stack(i)
301                 s := key(stk)
302                 if count := m[s]; count != 0 {
303                         fmt.Fprintf(w, "%d %s\n", count, s)
304                         if debug > 0 {
305                                 printStackRecord(w, stk, false)
306                         }
307                         delete(m, s)
308                 }
309         }
310
311         if tw != nil {
312                 tw.Flush()
313         }
314         return b.Flush()
315 }
316
317 // printStackRecord prints the function + source line information
318 // for a single stack trace.
319 func printStackRecord(w io.Writer, stk []uintptr, allFrames bool) {
320         show := allFrames
321         for _, pc := range stk {
322                 f := runtime.FuncForPC(pc)
323                 if f == nil {
324                         show = true
325                         fmt.Fprintf(w, "#\t%#x\n", pc)
326                 } else {
327                         file, line := f.FileLine(pc)
328                         name := f.Name()
329                         // Hide runtime.goexit and any runtime functions at the beginning.
330                         // This is useful mainly for allocation traces.
331                         if name == "runtime.goexit" || !show && strings.HasPrefix(name, "runtime.") {
332                                 continue
333                         }
334                         show = true
335                         fmt.Fprintf(w, "#\t%#x\t%s+%#x\t%s:%d\n", pc, f.Name(), pc-f.Entry(), file, line)
336                 }
337         }
338         if !show {
339                 // We didn't print anything; do it again,
340                 // and this time include runtime functions.
341                 printStackRecord(w, stk, true)
342                 return
343         }
344         fmt.Fprintf(w, "\n")
345 }
346
347 // Interface to system profiles.
348
349 type byInUseBytes []runtime.MemProfileRecord
350
351 func (x byInUseBytes) Len() int           { return len(x) }
352 func (x byInUseBytes) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
353 func (x byInUseBytes) Less(i, j int) bool { return x[i].InUseBytes() > x[j].InUseBytes() }
354
355 // WriteHeapProfile is shorthand for Lookup("heap").WriteTo(w, 0).
356 // It is preserved for backwards compatibility.
357 func WriteHeapProfile(w io.Writer) error {
358         return writeHeap(w, 0)
359 }
360
361 // countHeap returns the number of records in the heap profile.
362 func countHeap() int {
363         n, _ := runtime.MemProfile(nil, true)
364         return n
365 }
366
367 // writeHeap writes the current runtime heap profile to w.
368 func writeHeap(w io.Writer, debug int) error {
369         // Find out how many records there are (MemProfile(nil, true)),
370         // allocate that many records, and get the data.
371         // There's a race—more records might be added between
372         // the two calls—so allocate a few extra records for safety
373         // and also try again if we're very unlucky.
374         // The loop should only execute one iteration in the common case.
375         var p []runtime.MemProfileRecord
376         n, ok := runtime.MemProfile(nil, true)
377         for {
378                 // Allocate room for a slightly bigger profile,
379                 // in case a few more entries have been added
380                 // since the call to MemProfile.
381                 p = make([]runtime.MemProfileRecord, n+50)
382                 n, ok = runtime.MemProfile(p, true)
383                 if ok {
384                         p = p[0:n]
385                         break
386                 }
387                 // Profile grew; try again.
388         }
389
390         sort.Sort(byInUseBytes(p))
391
392         b := bufio.NewWriter(w)
393         var tw *tabwriter.Writer
394         w = b
395         if debug > 0 {
396                 tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
397                 w = tw
398         }
399
400         var total runtime.MemProfileRecord
401         for i := range p {
402                 r := &p[i]
403                 total.AllocBytes += r.AllocBytes
404                 total.AllocObjects += r.AllocObjects
405                 total.FreeBytes += r.FreeBytes
406                 total.FreeObjects += r.FreeObjects
407         }
408
409         // Technically the rate is MemProfileRate not 2*MemProfileRate,
410         // but early versions of the C++ heap profiler reported 2*MemProfileRate,
411         // so that's what pprof has come to expect.
412         fmt.Fprintf(w, "heap profile: %d: %d [%d: %d] @ heap/%d\n",
413                 total.InUseObjects(), total.InUseBytes(),
414                 total.AllocObjects, total.AllocBytes,
415                 2*runtime.MemProfileRate)
416
417         for i := range p {
418                 r := &p[i]
419                 fmt.Fprintf(w, "%d: %d [%d: %d] @",
420                         r.InUseObjects(), r.InUseBytes(),
421                         r.AllocObjects, r.AllocBytes)
422                 for _, pc := range r.Stack() {
423                         fmt.Fprintf(w, " %#x", pc)
424                 }
425                 fmt.Fprintf(w, "\n")
426                 if debug > 0 {
427                         printStackRecord(w, r.Stack(), false)
428                 }
429         }
430
431         // Print memstats information too.
432         // Pprof will ignore, but useful for people
433         if debug > 0 {
434                 s := new(runtime.MemStats)
435                 runtime.ReadMemStats(s)
436                 fmt.Fprintf(w, "\n# runtime.MemStats\n")
437                 fmt.Fprintf(w, "# Alloc = %d\n", s.Alloc)
438                 fmt.Fprintf(w, "# TotalAlloc = %d\n", s.TotalAlloc)
439                 fmt.Fprintf(w, "# Sys = %d\n", s.Sys)
440                 fmt.Fprintf(w, "# Lookups = %d\n", s.Lookups)
441                 fmt.Fprintf(w, "# Mallocs = %d\n", s.Mallocs)
442                 fmt.Fprintf(w, "# Frees = %d\n", s.Frees)
443
444                 fmt.Fprintf(w, "# HeapAlloc = %d\n", s.HeapAlloc)
445                 fmt.Fprintf(w, "# HeapSys = %d\n", s.HeapSys)
446                 fmt.Fprintf(w, "# HeapIdle = %d\n", s.HeapIdle)
447                 fmt.Fprintf(w, "# HeapInuse = %d\n", s.HeapInuse)
448                 fmt.Fprintf(w, "# HeapReleased = %d\n", s.HeapReleased)
449                 fmt.Fprintf(w, "# HeapObjects = %d\n", s.HeapObjects)
450
451                 fmt.Fprintf(w, "# Stack = %d / %d\n", s.StackInuse, s.StackSys)
452                 fmt.Fprintf(w, "# MSpan = %d / %d\n", s.MSpanInuse, s.MSpanSys)
453                 fmt.Fprintf(w, "# MCache = %d / %d\n", s.MCacheInuse, s.MCacheSys)
454                 fmt.Fprintf(w, "# BuckHashSys = %d\n", s.BuckHashSys)
455
456                 fmt.Fprintf(w, "# NextGC = %d\n", s.NextGC)
457                 fmt.Fprintf(w, "# PauseNs = %d\n", s.PauseNs)
458                 fmt.Fprintf(w, "# NumGC = %d\n", s.NumGC)
459                 fmt.Fprintf(w, "# EnableGC = %v\n", s.EnableGC)
460                 fmt.Fprintf(w, "# DebugGC = %v\n", s.DebugGC)
461         }
462
463         if tw != nil {
464                 tw.Flush()
465         }
466         return b.Flush()
467 }
468
469 // countThreadCreate returns the size of the current ThreadCreateProfile.
470 func countThreadCreate() int {
471         n, _ := runtime.ThreadCreateProfile(nil)
472         return n
473 }
474
475 // writeThreadCreate writes the current runtime ThreadCreateProfile to w.
476 func writeThreadCreate(w io.Writer, debug int) error {
477         return writeRuntimeProfile(w, debug, "threadcreate", runtime.ThreadCreateProfile)
478 }
479
480 // countGoroutine returns the number of goroutines.
481 func countGoroutine() int {
482         return runtime.NumGoroutine()
483 }
484
485 // writeGoroutine writes the current runtime GoroutineProfile to w.
486 func writeGoroutine(w io.Writer, debug int) error {
487         if debug >= 2 {
488                 return writeGoroutineStacks(w)
489         }
490         return writeRuntimeProfile(w, debug, "goroutine", runtime.GoroutineProfile)
491 }
492
493 func writeGoroutineStacks(w io.Writer) error {
494         // We don't know how big the buffer needs to be to collect
495         // all the goroutines.  Start with 1 MB and try a few times, doubling each time.
496         // Give up and use a truncated trace if 64 MB is not enough.
497         buf := make([]byte, 1<<20)
498         for i := 0; ; i++ {
499                 n := runtime.Stack(buf, true)
500                 if n < len(buf) {
501                         buf = buf[:n]
502                         break
503                 }
504                 if len(buf) >= 64<<20 {
505                         // Filled 64 MB - stop there.
506                         break
507                 }
508                 buf = make([]byte, 2*len(buf))
509         }
510         _, err := w.Write(buf)
511         return err
512 }
513
514 func writeRuntimeProfile(w io.Writer, debug int, name string, fetch func([]runtime.StackRecord) (int, bool)) error {
515         // Find out how many records there are (fetch(nil)),
516         // allocate that many records, and get the data.
517         // There's a race—more records might be added between
518         // the two calls—so allocate a few extra records for safety
519         // and also try again if we're very unlucky.
520         // The loop should only execute one iteration in the common case.
521         var p []runtime.StackRecord
522         n, ok := fetch(nil)
523         for {
524                 // Allocate room for a slightly bigger profile,
525                 // in case a few more entries have been added
526                 // since the call to ThreadProfile.
527                 p = make([]runtime.StackRecord, n+10)
528                 n, ok = fetch(p)
529                 if ok {
530                         p = p[0:n]
531                         break
532                 }
533                 // Profile grew; try again.
534         }
535
536         return printCountProfile(w, debug, name, runtimeProfile(p))
537 }
538
539 type runtimeProfile []runtime.StackRecord
540
541 func (p runtimeProfile) Len() int              { return len(p) }
542 func (p runtimeProfile) Stack(i int) []uintptr { return p[i].Stack() }
543
544 var cpu struct {
545         sync.Mutex
546         profiling bool
547         done      chan bool
548 }
549
550 // StartCPUProfile enables CPU profiling for the current process.
551 // While profiling, the profile will be buffered and written to w.
552 // StartCPUProfile returns an error if profiling is already enabled.
553 func StartCPUProfile(w io.Writer) error {
554         // The runtime routines allow a variable profiling rate,
555         // but in practice operating systems cannot trigger signals
556         // at more than about 500 Hz, and our processing of the
557         // signal is not cheap (mostly getting the stack trace).
558         // 100 Hz is a reasonable choice: it is frequent enough to
559         // produce useful data, rare enough not to bog down the
560         // system, and a nice round number to make it easy to
561         // convert sample counts to seconds.  Instead of requiring
562         // each client to specify the frequency, we hard code it.
563         const hz = 100
564
565         // Avoid queueing behind StopCPUProfile.
566         // Could use TryLock instead if we had it.
567         if cpu.profiling {
568                 return fmt.Errorf("cpu profiling already in use")
569         }
570
571         cpu.Lock()
572         defer cpu.Unlock()
573         if cpu.done == nil {
574                 cpu.done = make(chan bool)
575         }
576         // Double-check.
577         if cpu.profiling {
578                 return fmt.Errorf("cpu profiling already in use")
579         }
580         cpu.profiling = true
581         runtime.SetCPUProfileRate(hz)
582         go profileWriter(w)
583         return nil
584 }
585
586 func profileWriter(w io.Writer) {
587         for {
588                 data := runtime.CPUProfile()
589                 if data == nil {
590                         break
591                 }
592                 w.Write(data)
593         }
594         cpu.done <- true
595 }
596
597 // StopCPUProfile stops the current CPU profile, if any.
598 // StopCPUProfile only returns after all the writes for the
599 // profile have completed.
600 func StopCPUProfile() {
601         cpu.Lock()
602         defer cpu.Unlock()
603
604         if !cpu.profiling {
605                 return
606         }
607         cpu.profiling = false
608         runtime.SetCPUProfileRate(0)
609         <-cpu.done
610 }
611
612 type byCycles []runtime.BlockProfileRecord
613
614 func (x byCycles) Len() int           { return len(x) }
615 func (x byCycles) Swap(i, j int)      { x[i], x[j] = x[j], x[i] }
616 func (x byCycles) Less(i, j int) bool { return x[i].Cycles > x[j].Cycles }
617
618 // countBlock returns the number of records in the blocking profile.
619 func countBlock() int {
620         n, _ := runtime.BlockProfile(nil)
621         return n
622 }
623
624 // writeBlock writes the current blocking profile to w.
625 func writeBlock(w io.Writer, debug int) error {
626         var p []runtime.BlockProfileRecord
627         n, ok := runtime.BlockProfile(nil)
628         for {
629                 p = make([]runtime.BlockProfileRecord, n+50)
630                 n, ok = runtime.BlockProfile(p)
631                 if ok {
632                         p = p[:n]
633                         break
634                 }
635         }
636
637         sort.Sort(byCycles(p))
638
639         b := bufio.NewWriter(w)
640         var tw *tabwriter.Writer
641         w = b
642         if debug > 0 {
643                 tw = tabwriter.NewWriter(w, 1, 8, 1, '\t', 0)
644                 w = tw
645         }
646
647         fmt.Fprintf(w, "--- contention:\n")
648         fmt.Fprintf(w, "cycles/second=%v\n", runtime_cyclesPerSecond())
649         for i := range p {
650                 r := &p[i]
651                 fmt.Fprintf(w, "%v %v @", r.Cycles, r.Count)
652                 for _, pc := range r.Stack() {
653                         fmt.Fprintf(w, " %#x", pc)
654                 }
655                 fmt.Fprint(w, "\n")
656                 if debug > 0 {
657                         printStackRecord(w, r.Stack(), false)
658                 }
659         }
660
661         if tw != nil {
662                 tw.Flush()
663         }
664         return b.Flush()
665 }
666
667 func runtime_cyclesPerSecond() int64