MCPcopy Index your code
hub / github.com/coder/coder / DumpHandler

Function DumpHandler

cli/root.go:1192–1272  ·  view source on GitHub ↗

DumpHandler provides a custom SIGQUIT and SIGTRAP handler that dumps the stacktrace of all goroutines to stderr and a well-known file in the home directory. This is useful for debugging deadlock issues that may occur in production in workspaces, since the default Go runtime will only dump to stderr

(ctx context.Context, name string)

Source from the content-addressed store, hash-verified

1190//
1191// On Windows this immediately returns.
1192func DumpHandler(ctx context.Context, name string) {
1193 if runtime.GOOS == "windows" {
1194 // free up the goroutine since it'll be permanently blocked anyways
1195 return
1196 }
1197
1198 listenSignals := []os.Signal{syscall.SIGTRAP}
1199 if os.Getenv("GOTRACEBACK") != "crash" {
1200 listenSignals = append(listenSignals, syscall.SIGQUIT)
1201 }
1202
1203 sigs := make(chan os.Signal, 1)
1204 signal.Notify(sigs, listenSignals...)
1205 defer signal.Stop(sigs)
1206
1207 for {
1208 sigStr := ""
1209 select {
1210 case <-ctx.Done():
1211 return
1212 case sig := <-sigs:
1213 switch sig {
1214 case syscall.SIGQUIT:
1215 sigStr = "SIGQUIT"
1216 case syscall.SIGTRAP:
1217 sigStr = "SIGTRAP"
1218 }
1219 }
1220
1221 // Start with a 1MB buffer and keep doubling it until we can fit the
1222 // entire stacktrace, stopping early once we reach 64MB.
1223 buf := make([]byte, 1_000_000)
1224 stacklen := 0
1225 for {
1226 stacklen = runtime.Stack(buf, true)
1227 if stacklen < len(buf) {
1228 break
1229 }
1230 if 2*len(buf) > 64_000_000 {
1231 // Write a message to the end of the buffer saying that it was
1232 // truncated.
1233 const truncatedMsg = "\n\n\nstack trace truncated due to size\n"
1234 copy(buf[len(buf)-len(truncatedMsg):], truncatedMsg)
1235 break
1236 }
1237 buf = make([]byte, 2*len(buf))
1238 }
1239
1240 _, _ = fmt.Fprintf(os.Stderr, "%s:\n%s\n", sigStr, buf[:stacklen])
1241
1242 // Write to a well-known file.
1243 dir, err := os.UserHomeDir()
1244 if err != nil {
1245 dir = os.TempDir()
1246 }
1247 // Make the time filesystem-safe, for example ":" is not
1248 // permitted on many filesystems. Note that Z here only appends
1249 // Z to the string, it does not actually change the time zone.

Callers 3

proxyServerMethod · 0.92
ServerMethod · 0.85
workspaceAgentFunction · 0.85

Calls 10

ExitMethod · 0.80
StopMethod · 0.65
TempDirMethod · 0.65
FormatMethod · 0.65
CreateMethod · 0.65
WriteMethod · 0.65
CloseMethod · 0.65
NotifyMethod · 0.45
DoneMethod · 0.45
ErrorMethod · 0.45

Tested by

no test coverage detected