From 4002014cf8b321ade383a3b2c8223cae7dc8d3ee Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 2 May 2011 17:34:22 -0400 Subject: [PATCH] http/pprof: fix POST reading bug R=bradfitz CC=golang-dev https://golang.org/cl/4430075 --- src/cmd/prof/gopprof | 9 +++++---- src/pkg/http/pprof/pprof.go | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/cmd/prof/gopprof b/src/cmd/prof/gopprof index 8fa00cbe8c..8863fc6238 100755 --- a/src/cmd/prof/gopprof +++ b/src/cmd/prof/gopprof @@ -2880,17 +2880,18 @@ sub FetchSymbols { 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 bc79e21832..917c7f877a 100644 --- a/src/pkg/http/pprof/pprof.go +++ b/src/pkg/http/pprof/pprof.go @@ -26,6 +26,7 @@ package pprof import ( "bufio" + "bytes" "fmt" "http" "os" @@ -88,10 +89,14 @@ func Profile(w http.ResponseWriter, r *http.Request) { 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 @@ func Symbol(w http.ResponseWriter, r *http.Request) { 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()) }