Projects

Ticket #723 (closed defect: fixed)

Opened 21 months ago

Last modified 18 months ago

bug when calling the same variadic method multiple times with different arity

Reported by: jakub.suder@… Owned by: lsansonetti@…
Priority: major Milestone: MacRuby 0.7
Component: MacRuby Keywords: 0.7-blocker
Cc:

Description (last modified by martinlagardette@…) (diff)

I have a weird error related to NSSet.setWithObjects method and bindings. I'm not sure exactly what causes it, but my guess is that it's some kind of problem with methods that accept variable number of arguments, that only appears in some specific conditions. It took me a few hours to isolate only the relevant code, but I managed to cut it down to two small classes where changing anything else makes the error disappear (see attached zip with a project).

So I have a model class with 3 fields and 2 helper methods using those fields. For those 2 helper methods, I provide KVO methods keyPathsForValuesAffecting*** returning sets. In the app delegate, I create one instance of that class and 2 views, and bind two properties of the views to the methods in the model object.

When I get to NSSet.setWithObjects("sender", "recipient", nil) in keyPathsForValuesAffectingSenderAndRecipient, the application hangs.

Now, if I change anything in this code, it stops hanging; for example:

  • if I use NSSet.setWithArray(["sender", "recipient"]), it works
  • if I use a set with just "sender" (NSSet.setWithObjects("sender", nil)), it works
  • if I delete the second KVO method (keyPathsForValuesAffectingHasPicture), the first one starts working
  • if I don't bind the first view to keyPathsForValuesAffectingHasPicture, or change the order of bindings, it starts working
  • if I return a 2-element set in keyPathsForValuesAffectingHasPicture, it starts working (?!)
  • and here's the funniest one: if I copy the line NSSet.setWithObjects("sender", "recipient", nil) to application delegate, before the bindings, it works there, and the original invocation inside keyPathsForValuesAffectingSenderAndRecipient also magically starts working (?!?!)

As you can see, it's hard to figure out what's going on here... But as far as I can tell, this smells to me like some kind of bug related to memory, pointers pointing to wrong places and so on... (oh, good old C times... :)

And BTW, if I rewrite the model class (Message) in ObjC, it also starts working.

Tested on MacRuby 0.6.

Attachments

macblip_set_bindings_error.zip Download (22.4 KB) - added by jakub.suder@… 21 months ago.
archived project with the code causing the error
patch.diff Download (0.8 KB) - added by martinlagardette@… 18 months ago.

Change History

Changed 21 months ago by jakub.suder@…

archived project with the code causing the error

Changed 21 months ago by martinlagardette@…

  • description modified (diff)

Changed 21 months ago by martinlagardette@…

Breakpoint 1, 0x00007fff8523dc34 in auto_refcount_underflow_error ()
(gdb) bt
#0  0x00007fff8523dc34 in auto_refcount_underflow_error ()
#1  0x00007fff8524ac71 in Auto::Zone::dec_refcount_small_medium ()
#2  0x00007fff8524c75e in Auto::Zone::block_decrement_refcount ()
#3  0x00007fff85235a0f in auto_zone_release ()
#4  0x00007fff82eaf756 in _CFRelease ()
#5  0x00007fff88966ec0 in _CFURLCreateBookmarkDataFromFile ()
#6  0x00007fff82fbf858 in +[NSURL bookmarkDataWithContentsOfURL:error:] ()
#7  0x000000010110071c in ?? ()
#8  0x00000001001364e5 in __rb_vm_dispatch [inlined] () at /Users/naixn/Documents/Projets/MacRuby/dispatcher.cpp:450
#9  0x00000001001364e5 in rb_vm_dispatch () at dispatcher.cpp:1061
#10 0x00000001011002c2 in ?? ()
#11 0x0000000100154c8d in rb_vm_run (fname=0x2000d69e0 "/Users/naixn/Desktop/test.rb", node=0x2000d9500, binding=0x0, inside_eval=false) at vm.cpp:3708
#12 0x000000010003f6f1 in ruby_run_node (n=0x2000d9500) at eval.c:202
#13 0x0000000100000c15 in main (argc=2, argv=0x100f1cba0, envp=0x7fff5fbff7f0) at main.cpp:40
(gdb) 

Changed 21 months ago by martinlagardette@…

Sorry, this backtrace is not for this bug. My bad.

Changed 21 months ago by martinlagardette@…

This code can be reduced to the following:

framework "Foundation"
NSSet.setWithObjects("pictures", nil)
NSSet.setWithObjects("sender", "recipient", nil)

Just like Jakub said in his explanation, inverting the calls will make this work. I suspect this may have something to do with the stub generation, because the first call wil always work, and subsequent calls with lesser arguments will work just as well, but if you add more arguments than the first call, it will crash:

framework "Foundation"
NSSet.setWithObjects("1", "2", "3", "4", "5", "6", nil)
NSSet.setWithObjects("1", "2", "3", "4", "5", "6", "7", nil)

Changed 21 months ago by martinlagardette@…

I guess this would more or less confirm the stub generation error theory. With:

framework 'Cocoa'
p NSArray.arrayWithObjects("1", "2", "3", "4", "5", "6", nil)
p NSArray.arrayWithObjects("1", "2", "3", "4", "5", nil)
p NSArray.arrayWithObjects("1", "2", "3", "4", "5", "6", "7", nil)
$> macruby test.rb 
["1", "2", "3", "4", "5", "6"]
["1", "2", "3", "4", "5"]
Segmentation fault

Changed 18 months ago by lsansonetti@…

  • summary changed from nsset + bindings error to bug when calling the same variadic method multiple times with different arity

Renamed title accordingly.

Changed 18 months ago by lsansonetti@…

  • keywords 0.7-blocker added

Adding 0.7-blocker keyword.

Changed 18 months ago by martinlagardette@…

Changed 18 months ago by martinlagardette@…

Attached a patch that recaches when the current argc for a selector is different from the one in cache.

Changed 18 months ago by lsansonetti@…

The patch looked good, however when I merge it spec:ci fails immediately. Some debugging is needed :)

Changed 18 months ago by martinlagardette@…

As discussed, this is because the whole project needs to be recompiled.

However, it spec:ci only works if I use < argc instead of != argc (see below), which seems "lucky", which is why I'll investigate a little more.

Changed 18 months ago by martinlagardette@…

  • status changed from new to closed
  • resolution set to fixed
  • milestone set to MacRuby 0.7

Fixed with r4487 – the previously said problem doesn't exist anymore, it was probably due to some other code fixed recently.

Note: See TracTickets for help on using tickets.