I think I have constructed a minimal example which shows at least one instance of the memory corruption under 10.6 I am struggling with at the moment.

It is a stand-alone Cocoa app with just an NSView and one CALayer and an animation on it, that gets replaced every few seconds.
The relevant parts (I hope) of the source are at the end of this post.
(Sorry that this post is a bit lengthy!)

Often times I get an EXC_BAD_ACCESS right at the beginning, when - fobjc-gc is on (i.e., Garbage Collection = Supported in Xcode's Project Settings). Sometimes it is a SIG_ABORT.

The stack trace usually goes through -[NSView displayIfNeeded] -- I presume it's when the view tries to display for the first time.
It looks like this.

#0      0x7fff8249533c in objc_msgSend
#1      0x7fff87ea5820 in CABackingStoreUpdate
#2      0x7fff87ea4abf in -[CALayer _display]
#3      0x7fff87e635eb in CALayerDisplayIfNeeded
#4      0x7fff87e62a62 in CA::Context::commit_transaction
#5      0x7fff87e626b6 in CA::Transaction::commit
#6      0x7fff80c370b0 in -[NSView(NSLayerKitGlue) _drawRectAsLayerTree:]
#7      0x7fff80ad26e4 in -[NSView _drawRect:clip:]
#8 0x7fff80ad1ffd in -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] #9 0x7fff80ad2367 in -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] #10 0x7fff80ad2367 in -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] #11 0x7fff80ad06cf in -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView :] #12 0x7fff80ad01f3 in -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView :] #13 0x7fff80acca97 in -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]
#14     0x7fff80a46237 in -[NSView displayIfNeeded]

Or like this:

#0      0x7fff83e63ff6 in __kill
#1      0x7fff83f05072 in abort
#2      0x7fff8071a5d2 in __gnu_cxx::__verbose_terminate_handler
#3      0x7fff8249df49 in _objc_terminate
#4      0x7fff80718ae1 in __cxxabiv1::__terminate
#5      0x7fff80718b16 in std::terminate
#6      0x7fff80718bfc in __cxa_throw
#7      0x7fff8249a3b2 in objc_exception_throw
#8      0x7fff870acaf9 in -[NSException raise]
#9 0x7fff80accfdd in -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]
#10     0x7fff80a46237 in -[NSView displayIfNeeded]


Sometimes I also get this message on the console:

-[NSCFData drawLayer:inContext:]: unrecognized selector sent to instance 0x2000333c0


Sometimes, with no change in source code or settings, it does not crash, in fact it seems to run fine, *except* that there is a memory leak, i.e., with every fresh image the memory footprint grows! (which is even more weird (to me))


All of this does not happen (no crash, no mem leak), if Garbage Collection = Unsupported.


All kinds of suggestions, hints, or insights will be highly appreciated!

Regards,
Gabriel.


Here are the relevant parts of my source code.
If there is some important code missing, please let me know!


- (void) awakeFromNib
{
    mainLayer_ = [CALayer layer];
    mainLayer_.delegate = self;
    [self setLayer: mainLayer_];
    self.wantsLayer = YES;
    [self setNeedsDisplay: YES];
    [mainLayer_ setNeedsDisplay];
    currentLayer_ = [self makeImageLayer: @"img1" inRect: b.size];
    if ( currentLayer_ )
        [mainLayer_ addSublayer: currentLayer_ ];
    else
[self logMessage: [NSString stringWithFormat: @"creating initial layer failed", nil] asError: YES];

[NSTimer scheduledTimerWithTimeInterval: 5.0 target: self selector: @selector(replaceImage:) userInfo: nil repeats: YES];
}


- (void) replaceImage: (NSTimer *) theTimer
{
    [CATransaction begin];
[CATransaction setValue: [NSNumber numberWithFloat: 2.0f] forKey: kCATransactionAnimationDuration ];
    [currentLayer_ removeFromSuperlayer];
    // ...
    currentLayer_ = [self makeImageLayer: img_name_ inRect: b.size];
    [mainLayer_ addSublayer: currentLayer_ ];   
    [CATransaction commit];
    [self setNeedsDisplay: YES];
}

- (CALayer *) makeImageLayer: (NSString *) img_name inRect: (NSSize) size
{
    // load new image from disk
    NSBundle *thisBundle = [NSBundle bundleForClass:[self class]];
NSString * path = [thisBundle pathForResource: img_name ofType: @"jpg"];
    NSURL * url = [NSURL fileURLWithPath: path];
CGImageSourceRef sourceRef = CGImageSourceCreateWithURL ( (CFURLRef) url, NULL ); CGImageRef cgImage = CGImageSourceCreateImageAtIndex( sourceRef, 0, NULL );
    CFRelease(sourceRef);
        
    // create new layer containing the image
    CALayer* imgLayer = [CALayer layer];
    imgLayer.bounds = CGRectMake( 0.0, 0.0, size.width, size.height );
    imgLayer.contents = (id) cgImage;
imgLayer.contentsGravity = kCAGravityResizeAspect; // kCAGravityCenter;
    imgLayer.opacity = 1.0;
    imgLayer.position = CGPointMake( size.width/2.0, size.height/2.0 );

    // create animation for growing/shrinking
    // ...      
CABasicAnimation * anim = [CABasicAnimation animationWithKeyPath: @"bounds.size"];
    anim.toValue                = [NSValue valueWithSize: newsize];
    anim.fromValue              = [NSValue valueWithSize: size];
anim.timingFunction = [CAMediaTimingFunction functionWithName: kCAMediaTimingFunctionEaseOut];
    anim.duration               = ( random() % 10 + 5 ); // 5-10 seconds
    anim.autoreverses   = YES;
    anim.repeatCount    = 1e100;        // = forever
        
    [imgLayer addAnimation: anim forKey: @"size"];

    CGImageRelease( cgImage );
        
    return imgLayer;
}




Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to