diff --git a/ChangeLog b/ChangeLog index 4529a14a2..5e42fc444 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-03-08 Mike Kestner + + * glib/*.cs : add try/catch blocks to native callback + methods for DestroyNotify, Copy/Free, and ToggleNotify handlers. + Raise UnhandledException events on catches. + 2007-03-06 Mike Kestner * generator/Signal.cs : add try/catch blocks to native callback diff --git a/glib/DelegateWrapper.cs b/glib/DelegateWrapper.cs index 5fd4a9021..c02060212 100644 --- a/glib/DelegateWrapper.cs +++ b/glib/DelegateWrapper.cs @@ -96,10 +96,14 @@ namespace GLib { // object that owned the native delegate wrapper no longer // exists and the instance of the delegate itself is removed from the hash table. private void OnDestroy (IntPtr data) { - lock (typeof (DelegateWrapper)) { - if (instances.ContainsKey (this)) { - instances.Remove (this); + try { + lock (typeof (DelegateWrapper)) { + if (instances.ContainsKey (this)) { + instances.Remove (this); + } } + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); } } } diff --git a/glib/ExceptionManager.cs b/glib/ExceptionManager.cs index d275a9f79..5bc5f5464 100644 --- a/glib/ExceptionManager.cs +++ b/glib/ExceptionManager.cs @@ -55,6 +55,7 @@ namespace GLib { Console.Error.WriteLine ("Exception in Gtk# callback delegate"); Console.Error.WriteLine (" Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception."); Console.Error.WriteLine (e); + Console.Error.WriteLine (new System.Diagnostics.StackTrace (true)); Environment.Exit (1); } diff --git a/glib/Idle.cs b/glib/Idle.cs index 306053a39..4d4e108b9 100755 --- a/glib/Idle.cs +++ b/glib/Idle.cs @@ -27,6 +27,7 @@ namespace GLib { using System.Collections; using System.Runtime.InteropServices; + [CDeclCallback] public delegate bool IdleHandler (); public class Idle { @@ -40,12 +41,17 @@ namespace GLib { public bool Handler () { - IdleHandler idle_handler = (IdleHandler) real_handler; + try { + IdleHandler idle_handler = (IdleHandler) real_handler; - bool cont = idle_handler (); - if (!cont) - Remove (); - return cont; + bool cont = idle_handler (); + if (!cont) + Remove (); + return cont; + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } + return false; } } diff --git a/glib/ManagedValue.cs b/glib/ManagedValue.cs index 5923524d6..e61eed622 100644 --- a/glib/ManagedValue.cs +++ b/glib/ManagedValue.cs @@ -56,18 +56,28 @@ namespace GLib { static IntPtr Copy (IntPtr ptr) { - if (ptr == IntPtr.Zero) - return ptr; - GCHandle gch = (GCHandle) ptr; - return (IntPtr) GCHandle.Alloc (gch.Target); + try { + if (ptr == IntPtr.Zero) + return ptr; + GCHandle gch = (GCHandle) ptr; + return (IntPtr) GCHandle.Alloc (gch.Target); + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } + + return IntPtr.Zero; } static void Free (IntPtr ptr) { - if (ptr == IntPtr.Zero) - return; - GCHandle gch = (GCHandle) ptr; - gch.Free (); + try { + if (ptr == IntPtr.Zero) + return; + GCHandle gch = (GCHandle) ptr; + gch.Free (); + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } } public static IntPtr WrapObject (object obj) diff --git a/glib/Object.cs b/glib/Object.cs index 32f34d40e..997dbdff4 100644 --- a/glib/Object.cs +++ b/glib/Object.cs @@ -347,15 +347,19 @@ namespace GLib { void NotifyCallback (IntPtr handle, IntPtr pspec, IntPtr gch) { - GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal; - if (sig == null) - throw new Exception("Unknown signal GC handle received " + gch); + try { + GLib.Signal sig = ((GCHandle) gch).Target as GLib.Signal; + if (sig == null) + throw new Exception("Unknown signal GC handle received " + gch); - NotifyArgs args = new NotifyArgs (); - args.Args = new object[1]; - args.Args[0] = pspec; - NotifyHandler handler = (NotifyHandler) sig.Handler; - handler (GLib.Object.GetObject (handle), args); + NotifyArgs args = new NotifyArgs (); + args.Args = new object[1]; + args.Args[0] = pspec; + NotifyHandler handler = (NotifyHandler) sig.Handler; + handler (GLib.Object.GetObject (handle), args); + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } } void ConnectNotification (string signal, NotifyHandler handler) diff --git a/glib/Signal.cs b/glib/Signal.cs index 2e7d6a58b..fd43114fb 100644 --- a/glib/Signal.cs +++ b/glib/Signal.cs @@ -56,11 +56,15 @@ namespace GLib { delegate void SignalDestroyNotify (IntPtr data, IntPtr obj); static void OnNativeDestroy (IntPtr data, IntPtr obj) { - GCHandle gch = (GCHandle) data; - Signal s = gch.Target as Signal; - s.DisconnectHandler (s.before_id); - s.DisconnectHandler (s.after_id); - gch.Free (); + try { + GCHandle gch = (GCHandle) data; + Signal s = gch.Target as Signal; + s.DisconnectHandler (s.before_id); + s.DisconnectHandler (s.after_id); + gch.Free (); + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } } private Signal (GLib.Object obj, string signal_name, Delegate marshaler) diff --git a/glib/Timeout.cs b/glib/Timeout.cs index cc19142b8..cfe8d6692 100755 --- a/glib/Timeout.cs +++ b/glib/Timeout.cs @@ -24,6 +24,7 @@ namespace GLib { using System; using System.Runtime.InteropServices; + [CDeclCallback] public delegate bool TimeoutHandler (); public class Timeout { @@ -37,12 +38,17 @@ namespace GLib { public bool Handler () { - TimeoutHandler timeout_handler = (TimeoutHandler) real_handler; + try { + TimeoutHandler timeout_handler = (TimeoutHandler) real_handler; - bool cont = timeout_handler (); - if (!cont) - Remove (); - return cont; + bool cont = timeout_handler (); + if (!cont) + Remove (); + return cont; + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } + return false; } } diff --git a/glib/ToggleRef.cs b/glib/ToggleRef.cs index 5dfae840e..95db121cf 100644 --- a/glib/ToggleRef.cs +++ b/glib/ToggleRef.cs @@ -74,7 +74,7 @@ namespace GLib { if (weak.IsAlive) reference = weak.Target; else - throw new Exception ("Toggling dead object wrapper"); + throw new Exception ("Toggling dead wrapper"); } } @@ -83,9 +83,13 @@ namespace GLib { static void RefToggled (IntPtr data, IntPtr handle, bool is_last_ref) { - GCHandle gch = (GCHandle) data; - ToggleRef tref = gch.Target as ToggleRef; - tref.Toggle (is_last_ref); + try { + GCHandle gch = (GCHandle) data; + ToggleRef tref = gch.Target as ToggleRef; + tref.Toggle (is_last_ref); + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } } static ToggleNotifyHandler toggle_notify_callback; diff --git a/glib/WeakObject.cs b/glib/WeakObject.cs index ebe51bc45..7676d56a9 100644 --- a/glib/WeakObject.cs +++ b/glib/WeakObject.cs @@ -34,10 +34,14 @@ namespace GLib { delegate void DestroyNotify (IntPtr data); static void OnNativeDestroy (IntPtr data) { - GCHandle gch = (GCHandle) data; - WeakObject obj = gch.Target as WeakObject; - obj.Dispose (); - gch.Free (); + try { + GCHandle gch = (GCHandle) data; + WeakObject obj = gch.Target as WeakObject; + obj.Dispose (); + gch.Free (); + } catch (Exception e) { + ExceptionManager.RaiseUnhandledException (e, false); + } } void Dispose ()