No, there isn't. The http package would have to do the recovering.
> 1. Has this been reported (a search of the mailing list didn't show me
> anything)? It *may* be surious as I'm not totally certain I built with a
> stable go release. (I thought I built against the first "stable" release,
> but there's some chance I built against a random dev revision a bit after
> that...)
> panic: runtime error: integer divide by zero
>
> [signal 0x8 code=0x1 addr=0x56b9dc pc=0x56b9dc]
>
> runtime.panic+0xac /home/daniel/go/src/pkg/runtime/proc.c:1034
> runtime.panic(0x638020, 0xf8432f7df0)
> ----- stack segment boundary -----
> runtime.panicstring+0xa3 /home/daniel/go/src/pkg/runtime/runtime.c:116
> runtime.panicstring(0x7eed24, 0x560176)
> runtime.sigpanic+0x134 /home/daniel/go/src/pkg/runtime/linux/thread.c:298
> runtime.sigpanic()
> big.divWW+0xa /home/daniel/go/src/pkg/big/arith_amd64.s:59
> big.divWW(0xc38d50e195fe2dd1, 0x652ab5d2c5b4dc0a, 0x1ff, 0x130000000f,
> 0xf8441dd9b0, ...)
It looks to me like divWW was asked to divide
c38d50e195fe2dd1652ab5d2c5b4dc0a / 1ff,
which is not going to fit in a 64-bit quotient, so it trapped. It
looks like either memory
corruption or a bug in divLarge. Without the actual bigger numbers
involved it is hard
to say, and they are gone.
Russ
No, there isn't. The http package would have to do the recovering.
It looks to me like divWW was asked to divide
c38d50e195fe2dd1652ab5d2c5b4dc0a / 1ff,
which is not going to fit in a 64-bit quotient, so it trapped. It
looks like either memory
corruption or a bug in divLarge. Without the actual bigger numbers
involved it is hard
to say, and they are gone.
Probably.
Russ
I see the bug. Thanks for the detailed report.
Russ
Seems reasonable. I might just hang up.
> ... Does anyone else think it might be
> worthwhile for http to catch panics that don't originate in the user's code?
> I can think of a few different ways of modifying http to accomplish that...
Probably.
I see the bug. Thanks for the detailed report.
I've been debating doing that too. I haven't quite figured out the panic policies and when I can use them.Can I wrap each http connection's goroutine with a recover, and if it recovers in user code, serves a 500 with no details if nothing's been sent yet? But always log details?
func PanicProtectServeError(c http.ResponseWriter, req *http.Request) { if x := recover(); x != nil { fmt.Println("****Panic caught:", x) fmt.Println("While handling request:", req.RawURL) fmt.Println("\n", req.Header, "\n") if !HidePanics { panic(x) // go back to panicking } PrintCallStack(); fmt.Println("****Panic recovered. Returning error\n\n") c.WriteHeader(http.StatusInternalServerError) SendAdminMail("Panic caught (error served)!", fmt.Sprintf("panic: %s\r\v%s", x, CallStackToString()), false) } }
If a particular server wants something fancy it can do
that easily enough (look at the handlers Andrew and Rob
used in their talk at Google I/O this year).
> 3) The http.Server object lets the user specify a panic catching function,
> which it defers at the start of every goroutine.
> The code in http has changed a bit since I last read it, but I think 3 would
> be fairly easy to implement and the most flexible option. Users would give
> it a function like this one (copied from my code):
>
> func PanicProtectServeError(c http.ResponseWriter, req *http.Request) {
> if x := recover(); x != nil {
> fmt.Println("****Panic caught:", x)
> fmt.Println("While handling request:", req.RawURL)
> fmt.Println("\n", req.Header, "\n")
> if !HidePanics {
> panic(x) // go back to panicking
> }
> PrintCallStack();
> fmt.Println("****Panic recovered. Returning error\n\n")
> c.WriteHeader(http.StatusInternalServerError)
>
> SendAdminMail("Panic caught (error served)!", fmt.Sprintf("panic:
> %s\r\v%s", x, CallStackToString()), false)
> }
> }
This doesn't apply to your crash; the server failed before
it even got a chance to invoke a handler.
Russ
I am pretty sure the http package should just hang up.
If a particular server wants something fancy it can do
that easily enough (look at the handlers Andrew and Rob
used in their talk at Google I/O this year).
This doesn't apply to your crash; the server failed before
it even got a chance to invoke a handler.
Russ