Skip to content

Commit

Permalink
feat: add full goroutine stack dump
Browse files Browse the repository at this point in the history
  • Loading branch information
guseggert committed Mar 15, 2022
1 parent 04e7e95 commit cea6b14
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 0 deletions.
2 changes: 2 additions & 0 deletions bin/collect-profiles.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ fi
echo Collecting goroutine stacks
curl -s -o goroutines.stacks "$SOURCE_URL"'/debug/pprof/goroutine?debug=2'

curl -s -o goroutines.stacks.full "$SOURCE_URL"'/debug/stack'

echo Collecting goroutine profile
go tool pprof -symbolize=remote -svg -output goroutine.svg "$SOURCE_URL/debug/pprof/goroutine"

Expand Down
1 change: 1 addition & 0 deletions cmd/ipfs/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,7 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
corehttp.VersionOption(),
defaultMux("/debug/vars"),
defaultMux("/debug/pprof/"),
defaultMux("/debug/stack"),
corehttp.MutexFractionOption("/debug/pprof-mutex/"),
corehttp.BlockProfileRateOption("/debug/pprof-block/"),
corehttp.MetricsScrapingOption("/debug/metrics/prometheus"),
Expand Down
33 changes: 33 additions & 0 deletions cmd/ipfs/debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package main

import (
"io"
"net/http"
"runtime"
)

func init() {
http.HandleFunc("/debug/stack",
func(w http.ResponseWriter, _ *http.Request) {
_ = writeGoroutineStacks(w)
},
)
}

func writeGoroutineStacks(w io.Writer) error {
buf := make([]byte, 1<<20)
for i := 0; ; i++ {
n := runtime.Stack(buf, true)
if n < len(buf) {
buf = buf[:n]
break
}
// if len(buf) >= 64<<20 {
// // Filled 64 MB - stop there.
// break
// }
buf = make([]byte, 2*len(buf))
}
_, err := w.Write(buf)
return err
}
30 changes: 30 additions & 0 deletions core/commands/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,25 @@ However, it could reveal:
},
}

func writeAllGoroutineStacks(w io.Writer) error {
// this is based on pprof.writeGoroutineStacks, and removes the 64 MB limit
buf := make([]byte, 1<<20)
for i := 0; ; i++ {
n := runtime.Stack(buf, true)
if n < len(buf) {
buf = buf[:n]
break
}
// if len(buf) >= 64<<20 {
// // Filled 64 MB - stop there.
// break
// }
buf = make([]byte, 2*len(buf))
}
_, err := w.Write(buf)
return err
}

func writeProfiles(ctx context.Context, cpuProfileTime time.Duration, w io.Writer) error {
archive := zip.NewWriter(w)

Expand All @@ -143,6 +162,17 @@ func writeProfiles(ctx context.Context, cpuProfileTime time.Duration, w io.Write
file: "heap.pprof",
}}

{
out, err := archive.Create("goroutines-all.stacks")
if err != nil {
return err
}
err = writeAllGoroutineStacks(out)
if err != nil {
return err
}
}

for _, profile := range profiles {
prof := pprof.Lookup(profile.name)
out, err := archive.Create(profile.file)
Expand Down
4 changes: 4 additions & 0 deletions test/sharness/t0152-profile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,8 @@ test_expect_success "goroutines stacktrace is valid" '
grep -q "goroutine" "profiles/goroutines.stacks"
'

test_expect_success "full goroutines stacktrace is valid" '
grep -q "goroutine" "profiles/goroutines-all.stacks"
'

test_done

0 comments on commit cea6b14

Please sign in to comment.