diff options
| author | Egon Elbre <egonelbre@gmail.com> | 2020-09-23 14:06:28 +0300 |
|---|---|---|
| committer | Hajime Hoshi <hajimehoshi@gmail.com> | 2020-10-09 09:55:58 +0000 |
| commit | 33511fb959f8f0edd5e831a4b41523daf9d84e87 (patch) | |
| tree | c6a2ce9b43919d49b4ff95738bc5ecfa0e1085c7 /src/net/http | |
| parent | 2be7788f8383c2330cd96db53273e2995d4468f8 (diff) | |
| download | go-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.go | 60 |
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 +} |
