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.