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 mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id A6B297EE51 for ; Thu, 11 Apr 2013 09:11:41 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of berenger@riken.jp) identity=pra; client-ip=134.160.33.176; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="berenger@riken.jp"; x-sender="berenger@riken.jp"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of berenger@riken.jp designates 134.160.33.176 as permitted sender) identity=mailfrom; client-ip=134.160.33.176; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="berenger@riken.jp"; x-sender="berenger@riken.jp"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of postmaster@postman.riken.jp designates 134.160.33.176 as permitted sender) identity=helo; client-ip=134.160.33.176; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="berenger@riken.jp"; x-sender="postmaster@postman.riken.jp"; x-conformance=sidf_compatible; x-record-type="v=spf1" X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgUCANthZlGGoCGwnGdsb2JhbABQgzyvNJIXgRcOAQEBAQEGDQkJFCiCHwEBBAEnETYKBgsLGAkEEg8JAwIBAgEPJBITBgIBAQ4Jh2cDCQYMtS4DColdjEOCIDqDQQOJAIwdgWOBIYRihW+INg X-IPAS-Result: AgUCANthZlGGoCGwnGdsb2JhbABQgzyvNJIXgRcOAQEBAQEGDQkJFCiCHwEBBAEnETYKBgsLGAkEEg8JAwIBAgEPJBITBgIBAQ4Jh2cDCQYMtS4DColdjEOCIDqDQQOJAIwdgWOBIYRihW+INg X-IronPort-AV: E=Sophos;i="4.87,453,1363129200"; d="scan'208";a="10554977" Received: from postman4.riken.jp (HELO postman.riken.jp) ([134.160.33.176]) by mail3-smtp-sop.national.inria.fr with ESMTP; 11 Apr 2013 09:11:39 +0200 Received: from postman.riken.jp (postman4.riken.jp [127.0.0.1]) by postman.riken.jp (Postfix) with SMTP id 3380F8280BE for ; Thu, 11 Apr 2013 16:11:36 +0900 (JST) Received: from [172.27.98.103] (rikad98.riken.jp [134.160.214.98]) by postman.riken.jp (Postfix) with ESMTPA id A77877F8040 for ; Thu, 11 Apr 2013 16:11:35 +0900 (JST) Message-ID: <51666227.2040401@riken.jp> Date: Thu, 11 Apr 2013 16:11:35 +0900 From: Francois Berenger User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/20130308 Thunderbird/17.0.4 MIME-Version: 1.0 To: caml-list@inria.fr References: <4989654.hHte10Um7f@groupon> <87obdld161.fsf@li195-236.members.linode.com> <1725573.oORHJHkDHi@groupon> In-Reply-To: <1725573.oORHJHkDHi@groupon> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-PMX-Version: 5.6.0.2009776, Antispam-Engine: 2.7.2.376379, Antispam-Data: 2013.4.11.70316 Subject: Re: [Caml-list] try...finally , threads, stack-tracebacks .... in ocaml On 04/11/2013 03:42 PM, Chet Murthy wrote: > > 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. Isn't there a way to "trace" locking and unlocking of locks? So that you can do a post-mortem analysis of what went wrong. > 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? What is the ZAM? Regards, F. PS: I hate threads, but I _love_ processes ;) > --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 >