aboutsummaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorEgon Elbre <egonelbre@gmail.com>2020-09-23 14:06:28 +0300
committerHajime Hoshi <hajimehoshi@gmail.com>2020-10-09 09:55:58 +0000
commit33511fb959f8f0edd5e831a4b41523daf9d84e87 (patch)
treec6a2ce9b43919d49b4ff95738bc5ecfa0e1085c7 /src/net/http
parent2be7788f8383c2330cd96db53273e2995d4468f8 (diff)
downloadgo-33511fb959f8f0edd5e831a4b41523daf9d84e87.tar.xz
net/http/pprof: remove html/template dependency
html/template indirectly uses reflect MethodByName, this causes linker to use conservative mode resulting in larger binaries. The template here is trivial and can be replaced by string manipulation. This reduces a binary using only net/http/pprof by ~2.5MB. Fixes #41569 Change-Id: I240e1daa6376182ff4961997ee3ec7b96cb07be8 Reviewed-on: https://go-review.googlesource.com/c/go/+/256900 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Hajime Hoshi <hajimehoshi@gmail.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Hajime Hoshi <hajimehoshi@gmail.com> Trust: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/pprof/pprof.go60
1 files changed, 35 insertions, 25 deletions
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index 5ff7fdc3de..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"
@@ -352,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
@@ -368,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(),
})
@@ -386,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],
@@ -397,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>
@@ -418,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
+}