• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Serious crash from setNeedsDisplayInRect:
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Serious crash from setNeedsDisplayInRect:


  • Subject: Serious crash from setNeedsDisplayInRect:
  • From: Benjohn <email@hidden>
  • Date: Wed, 9 Feb 2005 11:27:26 +0000


Dear list,

Our application is crashing. I've built a small test case to recreate our application's behaviour, and this appears to crash in the same way. In summary, there seems to be a serious bug with setNeedsDisplayInRect:.

The test project is very simple, it's an NSView subclass that launches one worker threads to draw in to itself. I have placed the view's implementation at the bottom of this mail, along with GDB's stacks for the main thread and worker thread, and log output from the program running. I'd be delighted to mail an archive of the project to anyone who would like a look (I'll be putting it on to Apple's bug tracker in a few minutes).

A few points:

* I've put logging in to the view's dealloc call. This seems to get called for no reason I can see when the view is still visible. Presumably this is "not a good thing", and leads to the BAD ACCESS that happens. Why the view would be deallocated, I don't know. I can only presume that it's being caused by the framework.

* If "performSelectorOnMainThread:withObject:waitUntilDone:" is called with "waitUntilDone: YES", then the crash does not happen.

* The real application seems to crash sooner on G5 dual processor machines than on G4 dual processor machines. We've not seen the crash on single processor machines, but haven't tried hard to replicate it on such systems.

* Sometimes the test project and real app will be stable for a while (tens of minutes under various provocations). Sometimes they fall over almost immediately.

Unless there's something stupid I'm doing (which would be great), is there something wrong with Apple's framework? We think that we may be able to replace our "performSelectorOnMainThread:..." call with one that uses "waitUntilDone: YES". I would welcome other workaround suggestions.

The other obvious workaround is to simply call "setNeedsDisplayInRect:" from the worker thread, and this does not crash the test project (so far...). However, we originally used this approach, but found that some rects were being ignored. We found that calling "displayRect:" directly from workers did not loose rects, but did cause crashes. In our current code, the workers ask the main thread to call "displayRect:", but as found here, this causes intermittent crashes.


Thanks for any help, Cheers, Benjohn



Console Log [Note the view deallocation near bottom that shouldn't happen].
[Session started at 2005-02-09 11:05:57 +0000.]
GNU gdb 5.3-20030128 (Apple version gdb-330.1) (Fri Jul 16 21:42:28 GMT 2004)
Loading program into debugger…
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc-apple-darwin".
tty /dev/ttyp1
Program loaded.
run
[Switching to process 3229 local thread 0xd03]
Running…
2005-02-09 11:06:08.916 ThreadedPaintTest[3229] View has been deallocated.
Program received signal: "EXC_BAD_ACCESS".
(gdb)


Thread 1 (main thread)
#0 0x908311f4 in objc_msgSend
#1 0x9019f18c in CFArrayApplyFunction
#2 0x92dc57ac in -[NSView _propagateDirtyRectsToOpaqueAncestors]
#3 0x9019f18c in CFArrayApplyFunction
#4 0x92dc57ac in -[NSView _propagateDirtyRectsToOpaqueAncestors]
#5 0x92dee21c in -[NSView displayIfNeeded]
#6 0x92dfef4c in -[NSWindow displayIfNeeded]
#7 0x92ddf5ac in -[NSImage compositeToPoint:fromRect:operation:fraction:]
#8 0x90191ca0 in __CFRunLoopDoObservers
#9 0x9019153c in __CFRunLoopRun
#10 0x90195e8c in CFRunLoopRunSpecific
#11 0x927d5f60 in GetWindowList
#12 0x927dc6c8 in GetMainEventQueue
#13 0x927fe6a0 in BlockUntilNextEventMatchingListInMode
#14 0x92dd2e44 in _DPSNextEvent
#15 0x92de98c8 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
#16 0x92dfdc30 in -[NSApplication run]
#17 0x92eba2b8 in NSApplicationMain
#18 0x000e0f74 in main at main.m:13


Thread 2 (worker thread)
#0 0x90012568 in syscall_thread_switch
#1 0x90a029c8 in +[NSThread sleepUntilDate:]
#2 0x002ee64c in -[FLThreadedRepaintView forcePaintLoop] at FLThreadedRepaintView.mm:43
#3 0x90a39b74 in forkThreadForFunction
#4 0x900246e8 in _pthread_body



// FLThreadedRepaintView.mm #import "FLThreadedRepaintView.h"

@implementation FLThreadedRepaintView

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];

if (self)
{
[self setBounds: NSMakeRect(0.0f, 0.0f, 1.0f, 1.0f)];

// Start a worker thread on me.
[NSThread detachNewThreadSelector: @selector(forcePaintLoop) toTarget: self withObject: nil];
}


	return self;
}

- (void) dealloc
{
	NSLog(@"View has been deallocated.");
	[super dealloc];
}

#pragma mark -

- (void) forcePaintLoop
{
while( true )
{
NSAutoreleasePool *autoreleasePool = [[NSAutoreleasePool alloc] init];
[self forcePaints];
[NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: NormalisedRandom() * 0.1f]];
[autoreleasePool release];
}
}


- (void) forcePaints
{
for( int i=0; i<6; i++ )
{
[self performSelectorOnMainThread: @selector(forceDisplayOfRandomRect) withObject: nil waitUntilDone: NO];
}
}


- (void) forceDisplayOfRandomRect
{
	[self setNeedsDisplayInRect: RandomRect()];
}

#pragma mark -

- (void)drawRect:(NSRect)rect
{
    // Drawing code here.
	[RandomColour() set];
	[NSBezierPath fillRect: rect];
}

@end

NSRect RandomRect()
{
	const float x = 0.2f + 0.6f * NormalisedRandom();
	const float y = 0.2f + 0.6f * NormalisedRandom();
	return NSMakeRect( x-0.1f, y-0.1f, 0.1f, 0.1f );
}

NSColor *RandomColour()
{
return [NSColor colorWithCalibratedRed: NormalisedRandom() green: NormalisedRandom() blue: NormalisedRandom() alpha: 1.0f];
}


float NormalisedRandom()
{
	return float(rand() % 1000) / float(1000.0);
}

_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden


  • Follow-Ups:
    • Re: Serious crash from setNeedsDisplayInRect:
      • From: j o a r <email@hidden>
  • Prev by Date: NSTableView scrollRowToVisible
  • Next by Date: Statically linking *Obj-C* lib
  • Previous by thread: Re: NSTableView scrollRowToVisible
  • Next by thread: Re: Serious crash from setNeedsDisplayInRect:
  • Index(es):
    • Date
    • Thread