http/pprof: fix POST reading bug

R=bradfitz
CC=golang-dev
https://golang.org/cl/4430075
diff --git a/src/cmd/prof/gopprof b/src/cmd/prof/gopprof
index 8fa00cb..8863fc6 100755
--- a/src/cmd/prof/gopprof
+++ b/src/cmd/prof/gopprof
@@ -2880,17 +2880,18 @@
     my @toask = @pcs;
     while (@toask > 0) {
       my $n = @toask;
-      if ($n > 49) { $n = 49; }
+      # NOTE(rsc): Limiting the number of PCs requested per round
+      # used to be necessary, but I think it was a bug in
+      # debug/pprof/symbol's implementation.  Leaving here
+      # in case I am wrong.
+      # 	if ($n > 49) { $n = 49; }
       my @thisround = @toask[0..$n];
-my $t = @toask;
-print STDERR "$n $t\n";
       @toask = @toask[($n+1)..(@toask-1)];
       my $post_data = join("+", sort((map {"0x" . "$_"} @thisround)));
       open(POSTFILE, ">$main::tmpfile_sym");
       print POSTFILE $post_data;
       close(POSTFILE);
 
-print STDERR "SYMBL!\n";
       my $url = SymbolPageURL();
       $url = ResolveRedirectionForCurl($url);
       my $command_line = "$CURL -sd '\@$main::tmpfile_sym' '$url'";
diff --git a/src/pkg/http/pprof/pprof.go b/src/pkg/http/pprof/pprof.go
index bc79e21..917c7f8 100644
--- a/src/pkg/http/pprof/pprof.go
+++ b/src/pkg/http/pprof/pprof.go
@@ -26,6 +26,7 @@
 
 import (
 	"bufio"
+	"bytes"
 	"fmt"
 	"http"
 	"os"
@@ -88,10 +89,14 @@
 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(w, "num_symbols: 1\n")
+	fmt.Fprintf(&buf, "num_symbols: 1\n")
 
 	var b *bufio.Reader
 	if r.Method == "POST" {
@@ -109,14 +114,19 @@
 		if pc != 0 {
 			f := runtime.FuncForPC(uintptr(pc))
 			if f != nil {
-				fmt.Fprintf(w, "%#x %s\n", pc, f.Name())
+				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 != os.EOF {
+				fmt.Fprintf(&buf, "reading request: %v\n", err)
+			}
 			break
 		}
 	}
+
+	w.Write(buf.Bytes())
 }