EXC_BAD_ACCESS when -fobjc-gc is on (Was: Memory corruption ...)
EXC_BAD_ACCESS when -fobjc-gc is on (Was: Memory corruption ...)
- Subject: EXC_BAD_ACCESS when -fobjc-gc is on (Was: Memory corruption ...)
- From: Gabriel Zachmann <email@hidden>
- Date: Wed, 7 Oct 2009 20:13:17 +0200
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 (email@hidden)
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:
This email sent to email@hidden