[MacRuby-devel] [MacRuby] #221: rb_objc_ocval_to_rval crashing when returning Modal Panel Return values

MacRuby ruby-noreply at macosforge.org
Thu Feb 5 18:44:44 PST 2009


#221: rb_objc_ocval_to_rval crashing when returning Modal Panel Return values
-------------------------------------+--------------------------------------
 Reporter:  parzival@…               |       Owner:  lsansonetti@…        
     Type:  defect                   |      Status:  new                  
 Priority:  major                    |   Milestone:                       
Component:  MacRuby                  |    Keywords:                       
-------------------------------------+--------------------------------------
 My guess is that this is a problem in rb_objc_method_get_type, or in
 rb_objc_ocval_to_rval when dealing with objects of unknown type.
 It's causing my code to crash when trying to call the selector from an
 NSOpenPanel sheet.

 Here's a bit of the MacRuby code I'm working on:

 {{{
 oPanel.beginSheetForDirectory(nil, file: nil, types: nil, modalForWindow:
 spWindow, modalDelegate: self, didEndSelector:
 "mediaSourceSheetDidEnd:returnCode:contextInfo:", contextInfo: nil)
 end

 # Delegate (from modal sheet)
 def mediaSourceSheetDidEnd(oPanel, returnCode: rCode, contextInfo: cInfo)
     p oPanel    # <NSOpenPanel:0x1321300>
     p rCode    # nil, but only if 'cancel' was selected
     p cInfo  # nil
 end
 }}}
 Whenever a file is selected & 'Open' is pressed, it crashes with
 EXC_BAD_ACCESS.  If 'Cancel' is pressed, it proceeds but rcode is nil.
 Here's the trace of the crash:
 {{{
 Thread 1 (process 665 local thread 0x2d03):
 #0  0x002df287 in rb_objc_ocval_to_rval (ocval=0xbfffe0ac,
 octype=0xbfffdf4c "@", rbval=0xbfffdfcc) at objc.m:882
 #1  0x002e48d6 in rb_ruby_to_objc_closure_handler_main (ctx=0x12) at
 objc.m:1546
 #2  0x002e4bcb in rb_ruby_to_objc_closure_handler (cif=0x31d404,
 resp=0x31d404, args=0x31d404, userdata=0x31d404) at objc.m:1607
 #3  0x911af424 in ffi_closure_SYSV ()
 #4  0x92f0d2ae in -[NSSavePanel(NSSavePanelRuntime)
 _didEndSheet:returnCode:contextInfo:] ()
 #5  0x92d15233 in -[NSApplication endSheet:returnCode:] ()
 #6  0x92e5f7e1 in -[NSSavePanel(NSSavePanelRuntime) dismissWindow:] ()
 #7  0x92e5f69d in -[NSSavePanel(NSSavePanelRuntime) ok:] ()
 #8  0x92cd353b in -[NSApplication sendAction:to:from:] ()
 #9  0x92cd3478 in -[NSControl sendAction:to:] ()
 #10 0x92cd32fe in -[NSCell _sendActionFrom:] ()
 #11 0x92cd2957 in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] ()
 #12 0x92cd21aa in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:]
 ()
 #13 0x92cd1a64 in -[NSControl mouseDown:] ()
 #14 0x92cd01a3 in -[NSWindow sendEvent:] ()
 #15 0x92c9cd49 in -[NSApplication sendEvent:] ()
 #16 0x92bfa69f in -[NSApplication run] ()
 #17 0x92bc78a4 in NSApplicationMain ()
 #18 0x911af1dd in .LCFI1 ()
 #19 0x911af771 in ffi_call ()
 #20 0x002e45f0 in rb_bsfunc_call (bs_func=0x93bc1a0, sym=0x92bc7666,
 argc=2, argv=0x690050) at objc.m:1967
 #21 0x002d0b12 in vm_call_method (th=0x1013e50, cfp=0x70ff88, num=2,
 blockptr=0x1, flag=2145, id=<value temporarily unavailable, due to
 optimizations>, recv=16879904, klass=4267712, mcache=0x10a29c0) at
 vm_insnhelper.c:680
 #22 0x002c552e in vm_eval (th=0x1013e50, initial=<value temporarily
 unavailable, due to optimizations>) at insns.def:1067
 #23 0x002cbaab in vm_eval_body (th=0x1013e50) at vm.c:1032
 #24 0x002cbd14 in rb_iseq_eval (iseqval=17439584) at vm.c:1236
 #25 0x001f79d9 in ruby_exec_node (n=0x10a1b60, file=0x0) at eval.c:252
 #26 0x001fa9d0 in ruby_run_node (n=0x10a1b60) at eval.c:280
 #27 0x002de84b in macruby_main (path=0x1ff3 "rb_main.rb", argc=3,
 argv=0x4094a0) at objc.m:2834
 #28 0x00001fed in main (argc=1, argv=0xbffff788) at
 /Users/parzival/devo/buried/sinker/main.m:13
 Program received signal:  “EXC_BAD_ACCESS”.
 }}}

 Examining memory in the debugger, I can see that the memory holding the
 args in rb_ruby_to_objc_closure_handler_main is as follows:
 0xbfffe0a0: 01075510 093f5290 0134e070 00000001 00000000

 The last three are the arguments to be converted in rb_objc_ocval_to_rval,
 and the problem comes on the second one (when i=1), which is the return
 code from the panel. It's being treated as type 'id', and then the crash
 comes when attempting to dereference it as a'Class *'.

 I can also add that *ocval = 0x40.  The fact that NULL is treated as a
 special case in ocval_to_rval likely explains why it doesn't crash when
 'Cancel' is selected, since NSCancelButton = 0 by definition.

 I haven't looked at rb_objc_method_get_type so I can't say for sure that's
 it, but I would expect that NSCancel & NSOK ought to come back as
 integers.

 Thinking about it a bit more, it may be that hard to know what type these
 ought to be since it's not declared.  Is there a way to work that in to
 the beginSheet call?

 Substituting this function fails as well, however :

 {{{
 def mediaSourceSheetDidEnd(oPanel, returnCode: rCode, contextInfo: cInfo)

     if rCode == NSCancelButton
         puts "Canceled."
     end

     if rCode == NSOKButton
         puts "OK!"
     end

     p oPanel
     p rCode
     p cInfo
 end
 }}}

-- 
Ticket URL: <http://www.macruby.org/trac/ticket/221>
MacRuby <http://macruby.org/>



More information about the MacRuby-devel mailing list