From: Ian T Zimmerman <itz@transbay.net>
To: Xavier Leroy <Xavier.Leroy@inria.fr>
Cc: caml-list@inria.fr
Subject: Re: Catching Break?
Date: 05 Feb 1999 10:00:27 -0800 [thread overview]
Message-ID: <m2k8xwwx1g.fsf@kronstadt.transbay.net> (raw)
In-Reply-To: Xavier Leroy's message of Tue, 26 Jan 1999 01:24:35 +0100
Xavier Leroy <Xavier.Leroy@inria.fr> writes:
>
> > 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.
As I didn't get any further followups on this topic, I looked at the
bytecode compiler and interpreter. (As of Ocaml 2.01) I cannot see
the "function application" case being done:
kronstadt:/usr/src/ocaml-2.01/bytecomp$ grep -B 8 -e Kcheck_signals *.ml
bytegen.ml- comp_expr (add_var id (sz+1) env) handler (sz+1) (add_pop 1 cont1))
bytegen.ml- | Lifthenelse(cond, ifso, ifnot) ->
bytegen.ml- comp_binary_test env cond ifso ifnot sz cont
bytegen.ml- | Lsequence(exp1, exp2) ->
bytegen.ml- comp_expr env exp1 sz (comp_expr env exp2 sz cont)
bytegen.ml- | Lwhile(cond, body) ->
bytegen.ml- let lbl_loop = new_label() in
bytegen.ml- let lbl_test = new_label() in
bytegen.ml: Kbranch lbl_test :: Klabel lbl_loop :: Kcheck_signals ::
--
bytegen.ml- | Lfor(param, start, stop, dir, body) ->
bytegen.ml- let lbl_loop = new_label() in
bytegen.ml- let lbl_test = new_label() in
bytegen.ml- let offset = match dir with Upto -> 1 | Downto -> -1 in
bytegen.ml- let comp = match dir with Upto -> Cle | Downto -> Cge in
bytegen.ml- comp_expr env start sz
bytegen.ml- (Kpush :: comp_expr env stop (sz+1)
bytegen.ml- (Kpush :: Kbranch lbl_test ::
bytegen.ml: Klabel lbl_loop :: Kcheck_signals ::
--
emitcode.ml- out_int (Array.length tbl_const + (Array.length tbl_block lsl 16));
emitcode.ml- let org = !out_position in
emitcode.ml- Array.iter (out_label_with_orig org) tbl_const;
emitcode.ml- Array.iter (out_label_with_orig org) tbl_block
emitcode.ml- | Kboolnot -> out opBOOLNOT
emitcode.ml- | Kpushtrap lbl -> out opPUSHTRAP; out_label lbl
emitcode.ml- | Kpoptrap -> out opPOPTRAP
emitcode.ml- | Kraise -> out opRAISE
emitcode.ml: | Kcheck_signals -> out opCHECK_SIGNALS
--
instruct.ml- | Kbranchifnot of label
instruct.ml- | Kstrictbranchif of label
instruct.ml- | Kstrictbranchifnot of label
instruct.ml- | Kswitch of label array * label array
instruct.ml- | Kboolnot
instruct.ml- | Kpushtrap of label
instruct.ml- | Kpoptrap
instruct.ml- | Kraise
instruct.ml: | Kcheck_signals
--
printinstr.ml- Array.iter (fun lbl -> print_space(); print_int lbl) consts;
printinstr.ml- print_string "/";
printinstr.ml- Array.iter (fun lbl -> print_space(); print_int lbl) blocks;
printinstr.ml- close_box()
printinstr.ml- | Kboolnot -> print_string "\tboolnot"
printinstr.ml- | Kpushtrap lbl -> print_string "\tpushtrap L"; print_int lbl
printinstr.ml- | Kpoptrap -> print_string "\tpoptrap"
printinstr.ml- | Kraise -> print_string "\traise"
printinstr.ml: | Kcheck_signals -> print_string "\tcheck_signals"
So I'll see if inserting a dummy loop after the slow system call
helps. But yes something should be done about this.
I haven't even start to think what to do in the native code case...
--
Ian T Zimmerman <itz@transbay.net>
I came to the conclusion that what was wrong about the guillotine
was that the condemned man had no chance at all, absolutely none.
Albert Camus, _The Outsider_
next prev parent reply other threads:[~1999-02-08 8:02 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
1999-01-25 18:43 Ian T Zimmerman
1999-01-26 0:24 ` Xavier Leroy
1999-01-26 6:46 ` Ian T Zimmerman
1999-01-28 11:14 ` Xavier Leroy
1999-01-28 17:33 ` Ian T Zimmerman
1999-02-06 8:24 ` Ian T Zimmerman
1999-02-09 7:02 ` Ian T Zimmerman
1999-02-10 15:48 ` Xavier Leroy
1999-02-05 18:00 ` Ian T Zimmerman [this message]
1999-02-08 17:16 ` Xavier Leroy
1999-01-26 5:17 Frank A. Christoph
1999-01-26 11:23 Toby Moth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m2k8xwwx1g.fsf@kronstadt.transbay.net \
--to=itz@transbay.net \
--cc=Xavier.Leroy@inria.fr \
--cc=caml-list@inria.fr \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox