OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [http/] [pprof/] [pprof.go] - Rev 747

Compare with Previous | Blame | View Log

// Copyright 2010 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 pprof serves via its HTTP server runtime profiling data
// in the format expected by the pprof visualization tool.
// For more information about pprof, see
// http://code.google.com/p/google-perftools/.
//
// The package is typically only imported for the side effect of
// registering its HTTP handlers.
// The handled paths all begin with /debug/pprof/.
//
// To use pprof, link this package into your program:
//      import _ "http/pprof"
//
// Then use the pprof tool to look at the heap profile:
//
//      pprof http://localhost:6060/debug/pprof/heap
//
// Or to look at a 30-second CPU profile:
//
//      pprof http://localhost:6060/debug/pprof/profile
//
package pprof

import (
        "bufio"
        "bytes"
        "fmt"
        "io"
        "net/http"
        "os"
        "runtime"
        "runtime/pprof"
        "strconv"
        "strings"
        "time"
)

func init() {
        http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
        http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
        http.Handle("/debug/pprof/heap", http.HandlerFunc(Heap))
        http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
}

// Cmdline responds with the running program's
// command line, with arguments separated by NUL bytes.
// The package initialization registers it as /debug/pprof/cmdline.
func Cmdline(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")
        fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
}

// Heap responds with the pprof-formatted heap profile.
// The package initialization registers it as /debug/pprof/heap.
func Heap(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")
        pprof.WriteHeapProfile(w)
}

// Profile responds with the pprof-formatted cpu profile.
// The package initialization registers it as /debug/pprof/profile.
func Profile(w http.ResponseWriter, r *http.Request) {
        sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
        if sec == 0 {
                sec = 30
        }

        // Set Content Type assuming StartCPUProfile will work,
        // because if it does it starts writing.
        w.Header().Set("Content-Type", "application/octet-stream")
        if err := pprof.StartCPUProfile(w); err != nil {
                // StartCPUProfile failed, so no writes yet.
                // Can change header back to text content
                // and send error code.
                w.Header().Set("Content-Type", "text/plain; charset=utf-8")
                w.WriteHeader(http.StatusInternalServerError)
                fmt.Fprintf(w, "Could not enable CPU profiling: %s\n", err)
                return
        }
        time.Sleep(time.Duration(sec) * time.Second)
        pprof.StopCPUProfile()
}

// Symbol looks up the program counters listed in the request,
// responding with a table mapping program counters to function names.
// The package initialization registers it as /debug/pprof/symbol.
func Symbol(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Content-Type", "text/plain; charset=utf-8")

        // We have to read the whole POST body before
        // writing any output.  Buffer the output here.
        var buf bytes.Buffer

        // We don't know how many symbols we have, but we
        // do have symbol information.  Pprof only cares whether
        // this number is 0 (no symbols available) or > 0.
        fmt.Fprintf(&buf, "num_symbols: 1\n")

        var b *bufio.Reader
        if r.Method == "POST" {
                b = bufio.NewReader(r.Body)
        } else {
                b = bufio.NewReader(strings.NewReader(r.URL.RawQuery))
        }

        for {
                word, err := b.ReadSlice('+')
                if err == nil {
                        word = word[0 : len(word)-1] // trim +
                }
                pc, _ := strconv.ParseUint(string(word), 0, 64)
                if pc != 0 {
                        f := runtime.FuncForPC(uintptr(pc))
                        if f != nil {
                                fmt.Fprintf(&buf, "%#x %s\n", pc, f.Name())
                        }
                }

                // Wait until here to check for err; the last
                // symbol will have an err because it doesn't end in +.
                if err != nil {
                        if err != io.EOF {
                                fmt.Fprintf(&buf, "reading request: %v\n", err)
                        }
                        break
                }
        }

        w.Write(buf.Bytes())
}

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.