So, to give more background,  i am trying to porting a C based
interpreter to Go.  In the single threaded C code, the signal is
always handled by interrupting whatever code was executing and
directly exit after executing some "crash()" cleanup function.

Now, I ported the main function to Go, as I demonstrated above, there
is no way to "interrupt" C code anymore, so I can't run crash()
cleanly as before. This seems to be a limitation of Go, and I couldn't
think of any way to work around it.

On Wed, Feb 15, 2017 at 10:35 AM, Axel Wagner
<[email protected]> wrote:
> You misunderstood what I was trying to do (the recover was supposed to
> recover from any panic raised by the C-code, not from the panic of the main
> loop). And just added a new requirement.
>
> I don't think what you want is possible, from what I know about the go
> runtime. You could approximate it, by running C.do_anything and reading from
> the signal-channel alternately, but that would still delay any signal
> handling to after your C-code is done.
>
> But your requirements also seems more and more obscure to me; I could kind
> of understand why the C code and the cleanup code must run in the same
> goroutine/thread, but it seems obscure, that the asynchronous signal
> handling *also* needs to run in that thread.
>
> Anyway. Maybe someone else knows more about all of this than me and can help
> you :)
>
> On Wed, Feb 15, 2017 at 7:26 PM, Yucong Sun <[email protected]> wrote:
>>
>> Also, my cleanup function must be tied directly with C loop, because
>> they are sharing the same underlaying memory/state  . If I directly
>> run cleanup() while C loop was running, there could be race.
>>
>> So that leaves me with no choice, i must be able to panic on the C
>> loop's go-routine on async signals, which I can't do with current
>> tools.
>>
>> On Wed, Feb 15, 2017 at 10:21 AM, Yucong Sun <[email protected]> wrote:
>> > 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.

Reply via email to