caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Yaron Minsky <yminsky@janestreet.com>
To: Chet Murthy <murthy.chet@gmail.com>
Cc: Caml List <caml-list@inria.fr>
Subject: Re: [Caml-list] try...finally , threads, stack-tracebacks .... in ocaml
Date: Wed, 10 Apr 2013 19:35:34 -0400	[thread overview]
Message-ID: <CACLX4jSQZXKNFD1g-r7HOFjOjnLZJD92F_RrfSRWwfm2yxSD-A@mail.gmail.com> (raw)
In-Reply-To: <4989654.hHte10Um7f@groupon>

Chet, are you sure that one looses the stack trace in this case?  My
example using Core seems to preserve it.  Here's the code:

    open Core.Std

    let a () = let _ = "a" in raise Not_found
    let b () = let _ = "b" in a ()

    let c () =
      let _ = "c" in
      protect ~f:b
        ~finally:(fun () -> ())

    let d () = let _ = "d" in c ()
    let () = d ()

And here's the native code stack-trace:

    $ ./z.native
    Fatal error: exception Not_found
    Raised at file "z.ml", line 3, characters 32-41
    Called from file "lib/exn.ml", line 63, characters 8-11
    Re-raised at file "lib/exn.ml", line 66, characters 12-15
    Called from file "z.ml", line 11, characters 26-30

Here's the code for protect, which is a little different than your
finally, but not by a lot.  Maybe the biggest difference is that we
have a special exception (Finally) which we use when the finally
clause throws an exception from an exception handler, so we can
deliver both the exception tha triggered the [finally] and the
exception thrown by the [finally].

This is from the Exn module in Core.

    let protectx ~f x ~(finally : _ -> unit) =
      let res =
        try f x
        with exn ->
          (try finally x with final_exn -> raise (Finally (exn, final_exn)));
          raise exn
      in
      finally x;
      res
    ;;

    let protect ~f ~finally = protectx ~f () ~finally


On Wed, Apr 10, 2013 at 6:16 PM, Chet Murthy <murthy.chet@gmail.com> wrote:
>
> People have previously asked about try...finally support in Ocaml, and
> it's been observed (correctly) that you can write a little combinator
> to give you this support, e.g.
>
> let finally f arg finf =
>   let rv = try Inl(f arg) with e ->
>     Inr e
>   in (try finf arg rv with e -> ());
>         match rv with
>                 Inl v -> v
>           | Inr e -> raise e
>
> The problem is, you discard stack-traceback when you rethrow the
> exception.  One can program around this explicitly by capturing the
> backtrace string and appending it to the rethrown exception, but it's
> cumbersome and won't work for exceptions like Not_found that are
> already defined without a mutable string slot.
>
> It sure would be nice of ocaml had try...finally that preserved the
> traceback information properly .... though maybe it isn't possible.
> Certainly in the case where the finally block doesn't raise any
> exceptions itself (even those that are caught silently), it seems like
> it ought to be possible.
>
> In an unrelated but similar sense, when programming with threads in
> ocaml, it's easy (easy!) to deadlock your program.  Now, I've been
> writing Java programs for years, and so am aware of how careful one
> must be, and I'm writing my code using a single mutex protecting the
> critical section.  But I forgot and didn't mutex-protect one method --
> what merely printed out the contents of a shared daa-structure, and
> when that printout coincided with a thread actually mutating the
> data-structure, I got a deadlock.  Not hard to track down, and I
> chided myself for being lax.
>
> But the thing is, in Java (blecch!) I would have been able to use the
> "javacore" facility to get a full-thread stack-traceback, and could
> have used that to get a good idea of where my deadlock was.
>
> I'm not saying that this is something ocaml should have, but I figured
> I'd ask: are others (who use threads in ocaml) wishing for something
> like this?
>
> --chet--
>
>
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

  parent reply	other threads:[~2013-04-10 23:35 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-10 22:16 Chet Murthy
2013-04-10 22:28 ` simon cruanes
2013-04-11  0:19   ` Francois Berenger
2013-04-10 23:35 ` Yaron Minsky [this message]
2013-04-10 23:37   ` Yaron Minsky
2013-04-11  6:36     ` Malcolm Matalka
2013-04-11  6:42       ` Chet Murthy
2013-04-11  7:11         ` Francois Berenger
2013-04-11  7:17           ` Chet Murthy
2013-04-11  8:04             ` Roberto Di Cosmo
2013-04-11  8:48         ` Malcolm Matalka
2013-04-11 16:43           ` Chet Murthy
2013-04-11 11:13         ` Thomas Gazagnaire
2013-04-11  6:25 ` Jacques-Henri Jourdan

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=CACLX4jSQZXKNFD1g-r7HOFjOjnLZJD92F_RrfSRWwfm2yxSD-A@mail.gmail.com \
    --to=yminsky@janestreet.com \
    --cc=caml-list@inria.fr \
    --cc=murthy.chet@gmail.com \
    /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;
as well as URLs for NNTP newsgroup(s).