<font size=2 face="sans-serif">First, a confession: I'm new to the OS
X development world's modern APIs -- my experience lies mainly in the ancient
era (pre OS X/Carbon). I'm now working on a UI implementation that's NSWindow
/ NSView based for a large application and have jumped into this in MonoMac
/ MonoDevelop. So I'm not well-versed on the Objective-C layer either -
really just walked the plank and trying to tread water as I learn this.
:-)</font>
<br>
<br><font size=2 face="sans-serif">My situation is this:</font>
<br>
<br><font size=2 face="sans-serif">In a simple test application, I am trying
to get a feel for managing window lifetimes by simply having File>>New
create a new NSPanel. I've got a couple options to dump the app's window
list and also a "debug list" of weak references to the NSPanels
to see what happens w.r.t. the C# wrapper object lifetimes. I've tried
w/ and w/o creating a NSWindowController, but that seems to have no effect
w.r.t. crashing.</font>
<br>
<br><font size=2 face="sans-serif">I've set the NSPanel's ReleasedWhenClosed
to true. I also maintain a dictionary of NSPanel, NSWindowController pairs
so the C# GC doesn't start tossing things out on me. In a nutshell, here's
the "important" code:</font>
<br>
<br><font size=2 face="sans-serif">        public static
void NewPanel()</font>
<br><font size=2 face="sans-serif">        {</font>
<br><font size=2 face="sans-serif">           
NSPanel p = new NSPanel();</font>
<br><font size=2 face="sans-serif">           
_panels[p] = new NSWindowController(p); // stash a reference (or two) so
GC won't toss the NSPanel out</font>
<br><font size=2 face="sans-serif">           
p.StyleMask |= NSWindowStyle.Resizable | (NSWindowStyle)16 /* NSUtilityWindowMask
*/;</font>
<br><font size=2 face="sans-serif">           
p.FloatingPanel = true;</font>
<br><font size=2 face="sans-serif">           
p.Title = "Panel " + (++_panelNumber);</font>
<br><font size=2 face="sans-serif">           
p.ReleasedWhenClosed = true;</font>
<br><font size=2 face="sans-serif">           
p.WillClose += HandlePanelWillClose;</font>
<br>
<br><font size=2 face="sans-serif">           
_panelTracker[p.Title] = new WeakReference(p);</font>
<br>
<br><font size=2 face="sans-serif">           
p.IsVisible = true;</font>
<br><font size=2 face="sans-serif">           
System.Console.WriteLine(p.Title + " [" + p.Handle.ToString("X")
+ "]");</font>
<br><font size=2 face="sans-serif">        }</font>
<br>
<br><font size=2 face="sans-serif">        private
static void HandlePanelWillClose (object sender, EventArgs e)</font>
<br><font size=2 face="sans-serif">        {</font>
<br><font size=2 face="sans-serif">           
NSPanel p = (NSPanel)((NSNotification)sender).Object;</font>
<br><font size=2 face="sans-serif">           
bool removed = _panels.Remove(p);</font>
<br><font size=2 face="sans-serif">           
System.Console.WriteLine("Closing " + p.Title + "["
+ p.Handle.ToString("X") + "]; removed: " + removed
+ ", num in list: " + _panels.Count);</font>
<br><font size=2 face="sans-serif">           
DumpWeakReferenceList();</font>
<br><font size=2 face="sans-serif">        }</font>
<br>
<br><font size=2 face="sans-serif">        public static
void DumpWeakReferenceList()</font>
<br><font size=2 face="sans-serif">        {</font>
<br><font size=2 face="sans-serif">           
System.GC.Collect();</font>
<br><font size=2 face="sans-serif">           
System.Console.WriteLine("|---- Weak References List ----|");</font>
<br><font size=2 face="sans-serif">           
foreach (KeyValuePair<string, WeakReference> pair in _panelTracker)</font>
<br><font size=2 face="sans-serif">           
{</font>
<br><font size=2 face="sans-serif">           
    System.Console.WriteLine(pair.Key + " -> " +
pair.Value.IsAlive);</font>
<br><font size=2 face="sans-serif">           
}</font>
<br><font size=2 face="sans-serif">           
System.Console.WriteLine("");</font>
<br><font size=2 face="sans-serif">        }</font>
<br>
<br><font size=2 face="sans-serif">        public static
void DumpAppWindowList()</font>
<br><font size=2 face="sans-serif">        {</font>
<br><font size=2 face="sans-serif">           
System.GC.Collect();</font>
<br><font size=2 face="sans-serif">           
System.Console.WriteLine("|---- Window List ----|");</font>
<br><font size=2 face="sans-serif">           
foreach (NSWindow w in NSApplication.SharedApplication.Windows)</font>
<br><font size=2 face="sans-serif">           
{</font>
<br><font size=2 face="sans-serif">           
    System.Console.WriteLine(" > " + w.Title + "
[" + w.Handle.ToString("X") + "]");</font>
<br><font size=2 face="sans-serif">           
}</font>
<br><font size=2 face="sans-serif">           
System.Console.WriteLine("");</font>
<br><font size=2 face="sans-serif">        }</font>
<br>
<br><font size=2 face="sans-serif">At some point, inevitably, the app crashes
like this:</font>
<br>
<br><font size=2 face="sans-serif">  at (wrapper managed-to-native)
MonoMac.ObjCRuntime.Messaging.void_objc_msgSend (intptr,intptr) <IL
0x00024, 0xffffffff></font>
<br><font size=2 face="sans-serif">  at MonoMac.Foundation.NSObject/MonoMac_Disposer.Drain
(MonoMac.Foundation.NSObject) [0x0007b] in /cvs/monomac/src/Foundation/NSObject.cs:360</font>
<br><font size=2 face="sans-serif">  at (wrapper dynamic-method) object.[MonoMac.Foundation.NSObject+MonoMac_Disposer.Void
Drain(MonoMac.Foundation.NSObject)] (MonoMac.Foundation.NSObject,MonoMac.ObjCRuntime.Selector,MonoMac.Foundation.NSObject)
<IL 0x00011, 0x0004b></font>
<br><font size=2 face="sans-serif">  at (wrapper native-to-managed)
object.[MonoMac.Foundation.NSObject+MonoMac_Disposer.Void Drain(MonoMac.Foundation.NSObject)]
(MonoMac.Foundation.NSObject,MonoMac.ObjCRuntime.Selector,MonoMac.Foundation.NSObject)
<IL 0x000b6, 0xffffffff></font>
<br><font size=2 face="sans-serif">  at (wrapper managed-to-native)
MonoMac.AppKit.NSApplication.NSApplicationMain (int,string[]) <IL 0x0009d,
0xffffffff></font>
<br><font size=2 face="sans-serif">  at MonoMac.AppKit.NSApplication.Main
(string[]) [0x00000] in /cvs/monomac/src/AppKit/NSApplication.cs:74</font>
<br><font size=2 face="sans-serif">  at SimpleMonoApp.MainClass.Main
(string[]) [0x00005] in /Users/steveno/projects/NextGen/R2/PlatformFramework/Dev/SimpleMonoApp/Main.cs:14</font>
<br><font size=2 face="sans-serif">  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object
(object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff></font>
<br>
<br><font size=2 face="sans-serif">Native stacktrace:</font>
<br>
<br><font size=2 face="sans-serif">        0
  SimpleMonoApp                
      0x00094efc mono_handle_native_sigsegv + 284</font>
<br><font size=2 face="sans-serif">        1
  SimpleMonoApp                
      0x00004fe8 mono_sigsegv_signal_handler + 248</font>
<br><font size=2 face="sans-serif">        2
  libsystem_c.dylib              
    0x944bc59b _sigtramp + 43</font>
<br><font size=2 face="sans-serif">        3
  ???                  
              0xffffffff 0x0 + 4294967295</font>
<br><font size=2 face="sans-serif">        4
  ???                  
              0x05af3024 0x0 + 95367204</font>
<br><font size=2 face="sans-serif">        5
  ???                  
              0x01f59144 0x0 + 32870724</font>
<br><font size=2 face="sans-serif">        6
  ???                  
              0x01f4c43c 0x0 + 32818236</font>
<br><font size=2 face="sans-serif">        7
  CoreFoundation              
       0x946a6de1 -[NSObject performSelector:withObject:]
+ 65</font>
<br><font size=2 face="sans-serif">        8
  Foundation                
         0x9c4bde40 __NSThreadPerformPerform +
503</font>
<br><font size=2 face="sans-serif">        9
  CoreFoundation              
       0x9461e3df __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__
+ 15</font>
<br><font size=2 face="sans-serif">        10
 CoreFoundation                
     0x9461dd96 __CFRunLoopDoSources0 + 246</font>
<br><font size=2 face="sans-serif">        11
 CoreFoundation                
     0x94647c68 __CFRunLoopRun + 1112</font>
<br><font size=2 face="sans-serif">        12
 CoreFoundation                
     0x9464747c CFRunLoopRunSpecific + 332</font>
<br><font size=2 face="sans-serif">        13
 CoreFoundation                
     0x94647328 CFRunLoopRunInMode + 120</font>
<br><font size=2 face="sans-serif">        14
 AppKit                  
           0x918f720e _NSUnhighlightCarbonMenu
+ 199</font>
<br><font size=2 face="sans-serif">        15
 AppKit                  
           0x91900ae5 -[NSCarbonMenuImpl
performActionWithHighlightingForItemAtIndex:] + 204</font>
<br><font size=2 face="sans-serif">        16
 AppKit                  
           0x9190014d -[NSMenu _performActionWithHighlightingForItemAtIndex:sendAccessibilityNotification:]
+ 79</font>
<br><font size=2 face="sans-serif">        17
 AppKit                  
           0x919000f9 -[NSMenu _performActionWithHighlightingForItemAtIndex:]
+ 48</font>
<br><font size=2 face="sans-serif">        18
 AppKit                  
           0x91879933 -[NSMenu performKeyEquivalent:]
+ 306</font>
<br><font size=2 face="sans-serif">        19
 AppKit                  
           0x918783a2 -[NSApplication _handleKeyEquivalent:]
+ 594</font>
<br><font size=2 face="sans-serif">        20
 AppKit                  
           0x9176c4bf -[NSApplication sendEvent:]
+ 5772</font>
<br><font size=2 face="sans-serif">        21
 AppKit                  
           0x916fd6d5 -[NSApplication run]
+ 1007</font>
<br><font size=2 face="sans-serif">        22
 AppKit                  
           0x91991261 NSApplicationMain +
1054</font>
<br><font size=2 face="sans-serif">        23
 ???                  
              0x04103e6e 0x0 + 68173422</font>
<br><font size=2 face="sans-serif">        24
 ???                  
              0x04103c6c 0x0 + 68172908</font>
<br><font size=2 face="sans-serif">        25
 ???                  
              0x004a7ff8 0x0 + 4882424</font>
<br><font size=2 face="sans-serif">        26
 ???                  
              0x004a8156 0x0 + 4882774</font>
<br><font size=2 face="sans-serif">        27
 SimpleMonoApp                
      0x0000d282 mono_jit_runtime_invoke + 722</font>
<br><font size=2 face="sans-serif">        28
 SimpleMonoApp                
      0x001a436a mono_runtime_invoke + 170</font>
<br><font size=2 face="sans-serif">        29
 SimpleMonoApp                
      0x001a6f01 mono_runtime_exec_main + 705</font>
<br><font size=2 face="sans-serif">        30
 SimpleMonoApp                
      0x001a6111 mono_runtime_run_main + 929</font>
<br><font size=2 face="sans-serif">        31
 SimpleMonoApp                
      0x00069995 mono_jit_exec + 149</font>
<br><font size=2 face="sans-serif">        32
 SimpleMonoApp                
      0x0006bf13 mono_main + 9587</font>
<br><font size=2 face="sans-serif">        33
 SimpleMonoApp                
      0x00002299 main + 441</font>
<br><font size=2 face="sans-serif">        34
 SimpleMonoApp                
      0x000020a6 start + 54</font>
<br>
<br><font size=2 face="sans-serif">Debug info from gdb:</font>
<br>
<br>
<br><font size=2 face="sans-serif">=================================================================</font>
<br><font size=2 face="sans-serif">Got a SIGSEGV while executing native
code. This usually indicates</font>
<br><font size=2 face="sans-serif">a fatal error in the mono runtime or
one of the native libraries </font>
<br><font size=2 face="sans-serif">used by your application.</font>
<br><font size=2 face="sans-serif">=================================================================</font>
<br>
<br><font size=2 face="sans-serif">In the larger scope of things, those
"NSPanels" aren't going to just be a finite set of utility windows,
so keeping them around "forever" isn't an option. It may well
be that I'm doing something grossly incorrect, but in this simple app,
it should be easier to spot.</font>
<br>
<br><font size=2 face="sans-serif">Thanks for any insights / advice!</font>
<br>
<br><font size=2 face="sans-serif">-steve</font>