Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reporting Unrecovered Panics #968

Open
chodges15 opened this issue Feb 20, 2025 · 3 comments
Open

Reporting Unrecovered Panics #968

chodges15 opened this issue Feb 20, 2025 · 3 comments
Assignees

Comments

@chodges15
Copy link

Problem Statement

The current SDK will not report a panic if it isn't caught in a recover. The following example does not report any errors to Sentry. Panics and unhandled crashes are arguably the highest value errors an SRE would want to monitor and alert on in a production environment.

By default, Go will print the panic trace to stderr before exiting, but there is no opportunity for another go routine to recover the panic before the process terminates (note the absence of "Main exiting" in the output below).

There are a whole host of reasons a go program could panic, from data races to nil pointer dereferences, and there does not seem to be a good way to enforce panic recovery in every single go routine a developer might add to the codebase.

package main

import (
	"log"
	"time"
	"github.com/getsentry/sentry-go"
)

func main() {
	// Initialize Sentry SDK
	err := sentry.Init(sentry.ClientOptions{
		Dsn: "https://your-dsn@sentry.io/your-project",
		Debug: true,
	})
	if err != nil {
		log.Fatalf("sentry.Init: %s", err)
	}
	defer sentry.Flush(2 * time.Second)

	// Main goroutine recovery attempt (won't help)
	defer func() {
		if r := recover(); r != nil {
			log.Println("Main recovered:", r)
		}
	}()

	// Start problematic goroutine
	go func() {
		panic("goroutine panic - unrecovered")
	}()

	// Keep main alive to observe behavior
	time.Sleep(1 * time.Second)
	log.Println("Main exiting")
}

Ouputs:

...
[Sentry] 2025/02/20 16:41:01 Integration installed: GlobalTags
panic: goroutine panic - unrecovered

goroutine 24 [running]:
main.main.func2()
	/Users/chodges/go-panic/panic.go:29 +0x2c
created by main.main in goroutine 1
	/Users/chodges/go-panic/panic.go:28 +0xbc

Solution Brainstorm

Triggering a core dump is one way to get around this problem and report the error to Sentry, however that has its own set of drawbacks:

  • Exposes sensitive data
  • Generates large files which could fill the disk
  • High file I/O could compromise performance of the compute node

Another option would be to take a config option in the SDK initialization that has a file path to stderr output for the process. Then on SDK startup, it could go through the stderr output and look for panic stack traces and report them to Sentry. Parsing logs for errors is messy, but given how Golang handles unrecovered panics there is really nothing that can be done with error handling post-panic and before process termination.

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Feb 20, 2025
@cleptric
Copy link
Member

Our current thinking to support this would be some sort of wrapper program.
./sentry-panic-monitor <your-program> <your-program-args>, which would then parse and report panics to Sentry.
We do have some internal prototype which we still need to flesh out more, but would this be something that would work for you?

@chodges15
Copy link
Author

Hey @cleptric - yes, that makes a lot of sense and would work for us. When it's ready we'd like to build it from source, perhaps this wrapper would be included in this SDK repo?

@getsantry getsantry bot moved this to Waiting for: Product Owner in GitHub Issues with 👀 3 Feb 21, 2025
@cleptric
Copy link
Member

Yes, we'll add it to this repository.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: No status
Development

No branches or pull requests

2 participants