Version française
Home     About     Download     Resources     Contact us    
Browse thread
Catching Break?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Xavier Leroy <Xavier.Leroy@i...>
Subject: Re: Catching Break?
> Why doesn't this work:
> 
> let main() =
>   Sys.catch_break true;
>   try Unix.kill (Unix.getpid()) Sys.sigint
>   with Sys.Break -> prerr_endline "CAUGHT!"; exit 0
> 
> let _ = main()
> 
> This program just prints "Fatal error: Uncaught exception Sys.Break"
> as if the try block weren't there.  Am I overlooking something really
> obvious?

No, it's fairly subtle, actually.  For various reasons related to the
Caml runtime system, signals in OCaml are not necessarily handled at
the program point where they are received: the signal handler is
called only at the next "safe" program point.

In the case of the ocamlc bytecode interpreter, "safe" program points
are at function application and at the beginning of each loop iteration.
So, in your example above, we leave the "try..with" before the handler
for the signal is called, and that handler thus raises the Sys.Break
exception outside of the "try..with".

If you add a function call after the Unix.kill, everything should work
as expected:

> let main() =
>   Sys.catch_break true;
>   try Unix.kill (Unix.getpid()) Sys.sigint; prerr_endline "Sent signal"
>   with Sys.Break -> prerr_endline "CAUGHT!"; exit 0

This is actually a minor OCaml bug; it would be better to check for
pending signals just before leaving a "try..with" block.  I'll see
what can be done about it.

- Xavier Leroy