net/http/pprof: add tracing support

net/http/pprof part of tracing functionality:
https://docs.google.com/document/u/1/d/1FP5apqzBgr7ahCCgFO-yoVhk4YZrNIDNf9RybngBc14/pub
Full change:
https://codereview.appspot.com/146920043

Change-Id: I9092028fcbd5e8f97a56f2c155889ccdfb494afb
Reviewed-on: https://go-review.googlesource.com/1453
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/src/net/http/pprof/pprof.go b/src/net/http/pprof/pprof.go
index a23f1bc..f5a352d 100644
--- a/src/net/http/pprof/pprof.go
+++ b/src/net/http/pprof/pprof.go
@@ -34,6 +34,10 @@
 //
 //	go tool pprof http://localhost:6060/debug/pprof/block
 //
+// Or to collect a 5-second execution trace:
+//
+//	wget http://localhost:6060/debug/pprof/trace?seconds=5
+//
 // To view all available profiles, open http://localhost:6060/debug/pprof/
 // in your browser.
 //
@@ -64,6 +68,7 @@
 	http.Handle("/debug/pprof/cmdline", http.HandlerFunc(Cmdline))
 	http.Handle("/debug/pprof/profile", http.HandlerFunc(Profile))
 	http.Handle("/debug/pprof/symbol", http.HandlerFunc(Symbol))
+	http.Handle("/debug/pprof/trace", http.HandlerFunc(Trace))
 }
 
 // Cmdline responds with the running program's
@@ -98,6 +103,30 @@
 	pprof.StopCPUProfile()
 }
 
+// Trace responds with the execution trace in binary form.
+// Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.
+// The package initialization registers it as /debug/pprof/trace.
+func Trace(w http.ResponseWriter, r *http.Request) {
+	sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64)
+	if sec == 0 {
+		sec = 1
+	}
+
+	// Set Content Type assuming StartTrace will work,
+	// because if it does it starts writing.
+	w.Header().Set("Content-Type", "application/octet-stream")
+	if err := pprof.StartTrace(w); err != nil {
+		// StartTrace 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 tracing: %s\n", err)
+		return
+	}
+	time.Sleep(time.Duration(sec) * time.Second)
+	pprof.StopTrace()
+}
+
 // 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.