[MacRuby-devel] 0.2 available for testing

Laurent Sansonetti lsansonetti at apple.com
Thu Jun 5 22:27:27 PDT 2008


On Jun 5, 2008, at 9:53 PM, Stephen Bannasch wrote:

> At 2:58 PM -0700 6/5/08, Laurent Sansonetti wrote:
>> On Jun 5, 2008, at 2:41 PM, Stephen Bannasch wrote:
>>
>>> At 4:28 PM -0400 6/5/08, Richard Kilmer wrote:
>>>> On Jun 5, 2008, at 4:22 PM, Stephen Bannasch wrote:
>>>>> After clicking the Spin button the circle spins for a little  
>>>>> over 1s
>>>>> before the program crashes.
>>>>
>>>> Do you have the iPhone sdk installed by chance?
>>>
>>> No.
>>>
>>>> Just FYI, I svn up'd, built and CircleView runs just great.
>>>
>>> Hmmm ... is there a way to run it with gdb and watch the variable
>>> @layoutManager and break and display a stack frame when it is set to
>>> nil?
>>
>> It's not as easy.
>>
>> In rb_main.rb, add the following line at the very beginning of the  
>> file:
>>
>>  GC.disable
>>
>> Then, try to reproduce the bug. If it doesn't reproduce, then it's a
>> GC bug.
>
> I added GC.disable and clicking Spin worked. So it's a GC bug --  
> what do I need to look for to fix it?
>
> Before I disabled the GC I did this investigation:
>
>
> I setup a counter to find out how many times the  
> glyphRange.location.upto do loop is called.
>
>  def initWithFrame(frame)
>    super(frame)
>
>    @glyphRange_location_call_count = 0
>
> And then I added these debugging statements inside the  
> glyphRange.location.upto do loop
>
>    glyphRange.location.upto(glyphRange.location + glyphRange.length  
> - 1) do |i|
>      $stderr.puts "@layoutManager == nil: #{@layoutManger == nil},  
> times called: #{@glyphRange_location_call_count}"
>      @glyphRange_location_call_count += 1
>
> This is what happens when I start the app:
>
> [Session started at 2008-06-05 20:01:10 -0400.]
> @layoutManager == nil: true, times called: 0
> ...
> @layoutManager == nil: true, times called: 141
>
> Then I click the Spin button:
>
> #<NSCFTimer:0x16497e0>
> @layoutManager == nil: true, times called: 142
> @layoutManager == nil: true, times called: 143
> ...
> @layoutManager == nil: true, called: 2432
> @layoutManager == nil: true, called: 2433
> /Users/stephen/Desktop/CircleView/build/Release/CircleView.app/ 
> Contents/Resources/CircleView.rb:66:in `block in drawRect':  
> undefined method `+' for nil:NilClass (NoMethodError)
> 	from /Users/stephen/Desktop/CircleView/build/Release/CircleView.app/ 
> Contents/Resources/CircleView.rb:53:in `upto'
> 	from /Users/stephen/Desktop/CircleView/build/Release/CircleView.app/ 
> Contents/Resources/CircleView.rb:53:in `drawRect'
> 	from /Users/stephen/Desktop/CircleView/build/Release/CircleView.app/ 
> Contents/Resources/rb_main.rb:22:in `NSApplicationMain'
> 	from /Users/stephen/Desktop/CircleView/build/Release/CircleView.app/ 
> Contents/Resources/rb_main.rb:22:in `<main>'
>
> Ths is repeatable however the number of iterations before the crash  
> varies.
>
> I don't understand why @layoutManger appears to be nil the whole time.

So, I suspect the GC prematurely collect some ivars, including  
@layoutManager.

Fixing this problem is not easy, the bug is most probably in  
variable.c. One thing i would do is to setup a breakpoint in  
__rb_objc_finalize when *(Class *)obj == <the address of  
NSLayoutManager>. Then, verify why there is no reference to that object.

The problem: I cannot reproduce this crash. And all people I asked  
about also cannot reproduce it.

So, I will try to reproduce the crash by writing a small similar test  
case and stress the GC. In the meantime, I will still release 0.2  
tomorrow.

Laurent


More information about the MacRuby-devel mailing list