In gcc/objc/: 2011-04-15 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / libgo / go / http / pprof / pprof.go
blobbc79e218320cb9b0c4941866cc9fa01b85fe8ecb
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.
5 // Package pprof serves via its HTTP server runtime profiling data
6 // in the format expected by the pprof visualization tool.
7 // For more information about pprof, see
8 // http://code.google.com/p/google-perftools/.
9 //
10 // The package is typically only imported for the side effect of
11 // registering its HTTP handlers.
12 // The handled paths all begin with /debug/pprof/.
14 // To use pprof, link this package into your program:
15 // import _ "http/pprof"
17 // Then use the pprof tool to look at the heap profile:
19 // pprof http://localhost:6060/debug/pprof/heap
21 // Or to look at a 30-second CPU profile:
23 // pprof http://localhost:6060/debug/pprof/profile
25 package pprof
27 import (
28 "bufio"
29 "fmt"
30 "http"
31 "os"
32 "runtime"
33 "runtime/pprof"
34 "strconv"
35 "strings"
36 "time"
39 func init() {
40 http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
41 http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
42 http.Handle("/debug/pprof/heap", http.HandlerFunc(Heap))
43 http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
46 // Cmdline responds with the running program's
47 // command line, with arguments separated by NUL bytes.
48 // The package initialization registers it as /debug/pprof/cmdline.
49 func Cmdline(w http.ResponseWriter, r *http.Request) {
50 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
51 fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
54 // Heap responds with the pprof-formatted heap profile.
55 // The package initialization registers it as /debug/pprof/heap.
56 func Heap(w http.ResponseWriter, r *http.Request) {
57 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
58 pprof.WriteHeapProfile(w)
61 // Profile responds with the pprof-formatted cpu profile.
62 // The package initialization registers it as /debug/pprof/profile.
63 func Profile(w http.ResponseWriter, r *http.Request) {
64 sec, _ := strconv.Atoi64(r.FormValue("seconds"))
65 if sec == 0 {
66 sec = 30
69 // Set Content Type assuming StartCPUProfile will work,
70 // because if it does it starts writing.
71 w.Header().Set("Content-Type", "application/octet-stream")
72 if err := pprof.StartCPUProfile(w); err != nil {
73 // StartCPUProfile failed, so no writes yet.
74 // Can change header back to text content
75 // and send error code.
76 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
77 w.WriteHeader(http.StatusInternalServerError)
78 fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err)
79 return
81 time.Sleep(sec * 1e9)
82 pprof.StopCPUProfile()
85 // Symbol looks up the program counters listed in the request,
86 // responding with a table mapping program counters to function names.
87 // The package initialization registers it as /debug/pprof/symbol.
88 func Symbol(w http.ResponseWriter, r *http.Request) {
89 w.Header().Set("Content-Type", "text/plain; charset=utf-8")
91 // We don't know how many symbols we have, but we
92 // do have symbol information. Pprof only cares whether
93 // this number is 0 (no symbols available) or > 0.
94 fmt.Fprintf(w, "num_symbols: 1\n")
96 var b *bufio.Reader
97 if r.Method == "POST" {
98 b = bufio.NewReader(r.Body)
99 } else {
100 b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
103 for {
104 word, err := b.ReadSlice('+')
105 if err == nil {
106 word = word[0 : len(word)-1] // trim +
108 pc, _ := strconv.Btoui64(string(word), 0)
109 if pc != 0 {
110 f := runtime.FuncForPC(uintptr(pc))
111 if f != nil {
112 fmt.Fprintf(w, "%#x %s\n", pc, f.Name())
116 // Wait until here to check for err; the last
117 // symbol will have an err because it doesn't end in +.
118 if err != nil {
119 break