#221: rb_objc_ocval_to_rval crashing when returning Modal Panel Return values -------------------------------------+-------------------------------------- Reporter: parzi...@… | Owner: lsansone...@… 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/> _______________________________________________ MacRuby-devel mailing list MacRuby-devel@lists.macosforge.org http://lists.macosforge.org/mailman/listinfo.cgi/macruby-devel