https://play.golang.org/p/7Vz0o4ZoQF
shows that your code doesn't really work. My understanding is once panic reaches the current goroutine's top of callstack, program will crash, there are no attempt to call other goroutine's deferred function. So, in order to do what I want, i must be able to trigger some sort of inline panic remotely. Note in the C code this is easy, the signal handler will interrupt current thread, jump directly to the handler code and resume. If I can do that in golang, i will be able to trigger a panic in main() and do what I want (or do what the old C code does, which i was porting into go) On Wed, Feb 15, 2017 at 10:14 AM, Yucong Sun <[email protected]> wrote: > Thanks axle, but are you sure the code would work? it is essentially > triggering panic on the main go routine while recovering from another > goroutine, isn't that impossible? > > If this is possible, why couldn't I trigger a panic on a goroutine > then recover it from main goroutine? > > On Wed, Feb 15, 2017 at 10:03 AM, Axel Wagner > <[email protected]> wrote: >> First, the code you wrote here doesn't use os/signal, so you can't really >> fault Ian for giving that advice. Here's my understanding: >> >> In general, there are two kinds of signals: synchronous ones, raised e.g. by >> dereferencing invalid memory. They produce a runtime panic at the site that >> produced them in the corresponding goroutine. And asynchronous ones, raised >> e.g. by using the kill command or os.Kill. They do not produce a runtime >> panic but instead need to be handled via os/signal. >> >> Now, to "catch" asynchronous panic's, you need to use os/signal and if you >> need them to produce a runtime-panic on the goroutine running main, you need >> to read from that channel in main and produce a panic whenever you read a >> value. You could, for example, do this: >> >> func main() { >> ch := make(chan os.Signal) >> signal.Notify(ch, mySignals) >> >> errs := make(chan interface{}) >> >> go func() { >> defer func() { >> errs <- recover() >> }() >> for { >> C.do_something() >> } >> }() >> >> for { >> select { >> case s := <-ch: >> panic(fmt.Sprintf("received signal: %v", s)) >> case v := <-errs: >> panic(fmt.Sprintf("recovered runtime panic in C-code: %v", v)) >> } >> } >> } >> >> this will get asynchronous signals via os/signal and synchronous signals in >> the C-code raising runtime-panics via recover. >> >> Now, what is *not* possible, is to somehow recover from runtime panics >> caused by synchronous signals in *other* goroutines. The spec is pretty >> clear about that; a panic that isn't recovered will cause the program to >> crash. >> >> Hope this helps. >> >> On Wed, Feb 15, 2017 at 6:44 PM, Yucong Sun <[email protected]> wrote: >>> >>> hi, >>> >>> Maybe I wasn't clear, I am indeed using os.signal package. But it doesn't >>> do what I want! I want to trigger a panic in main function , seems there is >>> no way to do it by using a signal channel . >>> >>> Thanks >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "golang-nuts" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to [email protected]. >>> For more options, visit https://groups.google.com/d/optout. >> >> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
