From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 99E9C7EE5B for ; Thu, 11 Apr 2013 08:43:01 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of murthy.chet@gmail.com) identity=pra; client-ip=209.85.192.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="murthy.chet@gmail.com"; x-sender="murthy.chet@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of murthy.chet@gmail.com designates 209.85.192.180 as permitted sender) identity=mailfrom; client-ip=209.85.192.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="murthy.chet@gmail.com"; x-sender="murthy.chet@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-pd0-f180.google.com) identity=helo; client-ip=209.85.192.180; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="murthy.chet@gmail.com"; x-sender="postmaster@mail-pd0-f180.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsQGAKVaZlHRVcC0lGdsb2JhbABQgzyFXalXkheBARYOAQEBAQcLCwkSKoIfAQEFJxMGARsSDAMMBgUYCQQREA8BEQIRAQUBChIGExIJh2YBAw8MoEWML4J7hHkKGScDClmIfgEFDIw3giA6g0EDiQKMG4MEilGDOj+ETg X-IPAS-Result: AsQGAKVaZlHRVcC0lGdsb2JhbABQgzyFXalXkheBARYOAQEBAQcLCwkSKoIfAQEFJxMGARsSDAMMBgUYCQQREA8BEQIRAQUBChIGExIJh2YBAw8MoEWML4J7hHkKGScDClmIfgEFDIw3giA6g0EDiQKMG4MEilGDOj+ETg X-IronPort-AV: E=Sophos;i="4.87,453,1363129200"; d="scan'208";a="12757554" Received: from mail-pd0-f180.google.com ([209.85.192.180]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 11 Apr 2013 08:43:00 +0200 Received: by mail-pd0-f180.google.com with SMTP id q11so695087pdj.11 for ; Wed, 10 Apr 2013 23:42:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=x-received:from:to:subject:date:message-id:user-agent:in-reply-to :references:mime-version:content-transfer-encoding:content-type; bh=+C1PTLNi/1p40QgM0MoJhZpkJieyAmvQcB9s92r/bqw=; b=jTBqApgqCuCe5VOCYv16Qy7peHRid8oNZpiVQWG7MKsrjYBMlNNvu0UZbSdyhyAas/ 9A+asxWnSEtLbZskagqiqC6Rq+TLA4NsU1h7HYkzQa1/Tjlcnnj9L+G8jmjZ6mTMsByT HWZ+6DjCT0ACqcwKU9+f1f5caH8k6B/Ix1N1+qRwGfP0O4m0uh7D7/CcmztNMA2KHE86 GdmY60EfoUlQVOSXaEwJeTggoSxp0Yy56islgwkT3TxxZlFi5My9RTbmoG3WODttYOWn 4DSAsJmIPNtMy9x7mqtRU+qa5uKMexJM4x5an1O3HlE+dZAaoCvUCL2N4lOBw19r4BW1 rXDA== X-Received: by 10.66.50.7 with SMTP id y7mr7513318pan.179.1365662578758; Wed, 10 Apr 2013 23:42:58 -0700 (PDT) Received: from groupon.localnet (adsl-76-254-28-19.dsl.pltn13.sbcglobal.net. [76.254.28.19]) by mx.google.com with ESMTPS id im2sm2991375pbb.26.2013.04.10.23.42.56 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 10 Apr 2013 23:42:57 -0700 (PDT) From: Chet Murthy To: Caml List Date: Wed, 10 Apr 2013 23:42:47 -0700 Message-ID: <1725573.oORHJHkDHi@groupon> User-Agent: KMail/4.8.5 (Linux/3.2.0-38-generic-pae; KDE/4.8.5; i686; ; ) In-Reply-To: <87obdld161.fsf@li195-236.members.linode.com> References: <4989654.hHte10Um7f@groupon> <87obdld161.fsf@li195-236.members.linode.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Subject: Re: [Caml-list] try...finally , threads, stack-tracebacks .... in ocaml I agree that a monadic style would be nice. Of course, you'd lose even -more- of your stack (as it disappears into the continuation-chain). In this case, I'm working with code (Thrift) that relies on threads, and while I could fix it, right now is not the time. So threads are an externally-imposed requirement. Also, I notice that nobody's mentioned any sort of solution to "my threaded program deadlocked; I'm pretty sure I screwed up my locking -- how can I find out where the threads are stuck?" I'm not saying there -is- a solution: quite to the contrary. Multi-threaded programming (yes, even with a GIL) is here to say in Ocaml, and I think that the ability to get even a -rudimentary- "javacore"-like dump, would be useful. Even in just bytecode mode. It's been -forever- since I walked around in the ZAM, but Iguess sometime I'll have to take a look. In the meantime, does anybody out there have a -guess- as to the difficulty of getting such a dump out of the ZAM? --chet-- On Thursday, April 11, 2013 02:36:06 AM Malcolm Matalka wrote: > On top of this, I have also had a lot of success using the Result type > (and associated Monad) instead of Exceptions in Ocaml. You have to have > a certain level of discipline to enjoy doing it completely but I have > never had a stack-trace issue doing it because you already know where > you have to handle every failure case. > > /M > > Yaron Minsky writes: > > Oh, and as for the thread part of your point, I would strongly > > recommend using a monadic concurrency library like Async or Lwt rather > > than coding with system threads in OCaml. It does kill your > > stack-traces (stack-traces and monadic libraries don't work so well > > together), but it's totally worth the trade-off. Certainly your > > deadlock and race-condition problems get a hell of a lot better. > > > > y > > > > On Wed, Apr 10, 2013 at 7:35 PM, Yaron Minsky wrote: > >> 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 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