From: Olivier Andrieu MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16234.5256.398860.836871 at karryall.dnsalias.org> Date: Thu, 18 Sep 2003 22:24:40 +0200 To: Richard Jones Cc: lablgtk at kaba.or.jp Subject: Re: Exception handling bug in GMain.Main (was: Re: Trapping exceptions at the top level? (repost)) In-Reply-To: <20030918182103.GA26041 at redhat.com> References: <20030912101328J.garrigue at kurims.kyoto-u.ac.jp> <20030918182103.GA26041@redhat.com> Richard Jones [Thursday 18 September 2003] : > > On Fri, Sep 12, 2003 at 10:13:28AM +0900, Jacques Garrigue wrote: > > [This mail was sent by Richard Jones ] > > let rec run_main () = > > try > > GMain.Main.main () > > with > > Sys_error (...) -> > > (* Some code to post a message_box describing this error. *); > > run_main () > > I actually tried to implement this, but I've hit a Gtk/lablgtk bug. > Attached is the minimal example I made to reproduce the bug. Mind that even without the lablgtk bug, this wouldn't work : you're calling GMain.main () many times, but you're only calling GMain.quit twice. > Crash: > > GLib-GObject-ERROR **: file gsignal.c: line 646 (emission_pop): > should not be reached aborting... > Aborted Ouch. I do not get the message, only a segfault. Anyway ... > It looks like GMain.Main.main can't safely have exceptions passing > through it. Yeah, the stacktrace under gdb is a mess : all the Gtkbutton signal are stuck in the middle of their invocation but the caml program has jumped to a completely different part of the program (with a new main loop etc.) I'm not sure it's safe to let exceptions escape the callbacks ever. A simple solution is to modify GtkSignal to trap all exceptions raised by callbacks and run a user-exception handler (like yours that display a message box). That way the main loop is never exited because of a jump due to an exception. I tried it, it works quite well. Here's how it looks : ,---- | let display_error title msg = | let icon = GMisc.image () in | icon#set_stock `DIALOG_ERROR; | icon#set_icon_size `DIALOG; | GToolbox.message_box ~title ~icon msg | | let my_exn_handler = function | | Unix_error (err, syscall, filename) -> | display_error | "Filesystem error" | (syscall ^ ": " ^ filename ^ ": " ^ error_message err) | | Sys_error err -> | display_error | "System error" | err | | Failure err -> | display_error | "Internal error" | ("You probably found a bug in this software:\n\n" ^ err) | | exn -> () | | let _ = GtkSignal.user_exn_handler := my_exn_handler | | let () = | (* rest of the program ... *) `---- -- Olivier