aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/pprof
diff options
context:
space:
mode:
authorKatie Hockman <katie@golang.org>2020-12-14 10:03:05 -0500
committerKatie Hockman <katie@golang.org>2020-12-14 10:06:13 -0500
commit0345ede87ee12698988973884cfc0fd3d499dffd (patch)
tree7123cff141ee5661208d2f5f437b8f5252ac7f6a /src/net/http/pprof
parent4651d6b267818b0e0d128a5443289717c4bb8cbc (diff)
parent0a02371b0576964e81c3b40d328db9a3ef3b031b (diff)
downloadgo-0345ede87ee12698988973884cfc0fd3d499dffd.tar.xz
[dev.fuzz] all: merge master into dev.fuzz
Change-Id: I5d8c8329ccc9d747bd81ade6b1cb7cb8ae2e94b2
Diffstat (limited to 'src/net/http/pprof')
-rw-r--r--src/net/http/pprof/pprof.go72
-rw-r--r--src/net/http/pprof/pprof_test.go6
2 files changed, 42 insertions, 36 deletions
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index 81df0448e9..2bfcfb9545 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -61,11 +61,12 @@ import (
"bytes"
"context"
"fmt"
- "html/template"
+ "html"
"internal/profile"
"io"
"log"
"net/http"
+ "net/url"
"os"
"runtime"
"runtime/pprof"
@@ -93,14 +94,10 @@ func Cmdline(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, strings.Join(os.Args, "\x00"))
}
-func sleep(w http.ResponseWriter, d time.Duration) {
- var clientGone <-chan bool
- if cn, ok := w.(http.CloseNotifier); ok {
- clientGone = cn.CloseNotify()
- }
+func sleep(r *http.Request, d time.Duration) {
select {
case <-time.After(d):
- case <-clientGone:
+ case <-r.Context().Done():
}
}
@@ -142,7 +139,7 @@ func Profile(w http.ResponseWriter, r *http.Request) {
fmt.Sprintf("Could not enable CPU profiling: %s", err))
return
}
- sleep(w, time.Duration(sec)*time.Second)
+ sleep(r, time.Duration(sec)*time.Second)
pprof.StopCPUProfile()
}
@@ -171,7 +168,7 @@ func Trace(w http.ResponseWriter, r *http.Request) {
fmt.Sprintf("Could not enable tracing: %s", err))
return
}
- sleep(w, time.Duration(sec*float64(time.Second)))
+ sleep(r, time.Duration(sec*float64(time.Second)))
trace.Stop()
}
@@ -356,6 +353,13 @@ var profileDescriptions = map[string]string{
"trace": "A trace of execution of the current program. You can specify the duration in the seconds GET parameter. After you get the trace file, use the go tool trace command to investigate the trace.",
}
+type profileEntry struct {
+ Name string
+ Href string
+ Desc string
+ Count int
+}
+
// Index responds with the pprof-formatted profile named by the request.
// For example, "/debug/pprof/heap" serves the "heap" profile.
// Index responds to a request for "/debug/pprof/" with an HTML page
@@ -372,17 +376,11 @@ func Index(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("Content-Type", "text/html; charset=utf-8")
- type profile struct {
- Name string
- Href string
- Desc string
- Count int
- }
- var profiles []profile
+ var profiles []profileEntry
for _, p := range pprof.Profiles() {
- profiles = append(profiles, profile{
+ profiles = append(profiles, profileEntry{
Name: p.Name(),
- Href: p.Name() + "?debug=1",
+ Href: p.Name(),
Desc: profileDescriptions[p.Name()],
Count: p.Count(),
})
@@ -390,7 +388,7 @@ func Index(w http.ResponseWriter, r *http.Request) {
// Adding other profiles exposed from within this package
for _, p := range []string{"cmdline", "profile", "trace"} {
- profiles = append(profiles, profile{
+ profiles = append(profiles, profileEntry{
Name: p,
Href: p,
Desc: profileDescriptions[p],
@@ -401,12 +399,14 @@ func Index(w http.ResponseWriter, r *http.Request) {
return profiles[i].Name < profiles[j].Name
})
- if err := indexTmpl.Execute(w, profiles); err != nil {
+ if err := indexTmplExecute(w, profiles); err != nil {
log.Print(err)
}
}
-var indexTmpl = template.Must(template.New("index").Parse(`<html>
+func indexTmplExecute(w io.Writer, profiles []profileEntry) error {
+ var b bytes.Buffer
+ b.WriteString(`<html>
<head>
<title>/debug/pprof/</title>
<style>
@@ -422,22 +422,28 @@ var indexTmpl = template.Must(template.New("index").Parse(`<html>
Types of profiles available:
<table>
<thead><td>Count</td><td>Profile</td></thead>
-{{range .}}
- <tr>
- <td>{{.Count}}</td><td><a href={{.Href}}>{{.Name}}</a></td>
- </tr>
-{{end}}
-</table>
+`)
+
+ for _, profile := range profiles {
+ link := &url.URL{Path: profile.Href, RawQuery: "debug=1"}
+ fmt.Fprintf(&b, "<tr><td>%d</td><td><a href='%s'>%s</a></td></tr>\n", profile.Count, link, html.EscapeString(profile.Name))
+ }
+
+ b.WriteString(`</table>
<a href="goroutine?debug=2">full goroutine stack dump</a>
<br/>
<p>
Profile Descriptions:
<ul>
-{{range .}}
-<li><div class=profile-name>{{.Name}}:</div> {{.Desc}}</li>
-{{end}}
-</ul>
+`)
+ for _, profile := range profiles {
+ fmt.Fprintf(&b, "<li><div class=profile-name>%s: </div> %s</li>\n", html.EscapeString(profile.Name), html.EscapeString(profile.Desc))
+ }
+ b.WriteString(`</ul>
</p>
</body>
-</html>
-`))
+</html>`)
+
+ _, err := w.Write(b.Bytes())
+ return err
+}
diff --git a/src/net/http/pprof/pprof_test.go b/src/net/http/pprof/pprof_test.go
index f6f9ef5b04..84757e401a 100644
--- a/src/net/http/pprof/pprof_test.go
+++ b/src/net/http/pprof/pprof_test.go
@@ -8,7 +8,7 @@ import (
"bytes"
"fmt"
"internal/profile"
- "io/ioutil"
+ "io"
"net/http"
"net/http/httptest"
"runtime"
@@ -63,7 +63,7 @@ func TestHandlers(t *testing.T) {
t.Errorf("status code: got %d; want %d", got, want)
}
- body, err := ioutil.ReadAll(resp.Body)
+ body, err := io.ReadAll(resp.Body)
if err != nil {
t.Errorf("when reading response body, expected non-nil err; got %v", err)
}
@@ -227,7 +227,7 @@ func query(endpoint string) (*profile.Profile, error) {
return nil, fmt.Errorf("failed to fetch %q: %v", url, r.Status)
}
- b, err := ioutil.ReadAll(r.Body)
+ b, err := io.ReadAll(r.Body)
r.Body.Close()
if err != nil {
return nil, fmt.Errorf("failed to read and parse the result from %q: %v", url, err)