• 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
Arbitrary polygons crash -[NSBezierPath stroke]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Arbitrary polygons crash -[NSBezierPath stroke]


  • Subject: Arbitrary polygons crash -[NSBezierPath stroke]
  • From: Tom Bernard <email@hidden>
  • Date: Tue, 27 Jun 2006 17:05:54 -0600

Why do arbitrary polygons cause -[NSBezierPath stroke] to crash?
-[NSBezierPath fill] fills these polygons without incident. -stroke and
-fill accept other polygons without incident.

I have written a screensaver that creates objects, draws these objects on
the screen, ages the objects to maturity, then allows the objects to move
beyond the edge of the screen where they die. Objects may be stroked or
filled.

Stroked polygons sometimes crash. Filled polygons always draw. I have ruled
out premature release of the polygon, which is often a problem reported in
these archives. I have sometimes seen crashes caused by changing the view's
bounds. I have verified that I have not changed the bounds, nor has anything
changed the bounds behind my back.

Here are two methods, -[CirclesScreenSaverView drawRect:], and -[BISPolygon
draw] which is called by -drawRect:

- (void)drawRect:(NSRect)rect
{
    OnScreenObject    *anOnScreenObject;
    NSEnumerator    *enumerator;
    int            i;

    // erase the whole view once, otherwise, erase each object

    // if (viewNeedsErase || theControllerData.showGrid || [self isPreview])
    if (viewNeedsErase || theControllerData.showGrid)
    {
        [eraseColor set];
        [NSBezierPath fillRect:rect];

        viewNeedsErase = NO;
    }
    else
    {
        [eraseColor set];
        enumerator = [objectArray objectEnumerator];
        while (anOnScreenObject = [enumerator nextObject])
        {
            [anOnScreenObject erase];
            if (theControllerData.showOnScreenObjectLabel) [anOnScreenObject
eraseOnScreenObjectLabel];
        }
    }


    ...

    // kill objects that are ready to die

    enumerator = [executionList objectEnumerator];
    while (anOnScreenObject = [enumerator nextObject])
    {
        [anOnScreenObject die];
        [objectArray removeObject:anOnScreenObject];
    }
    [executionList removeAllObjects];


    // draw the remaining objects

    enumerator = [objectArray objectEnumerator];
    while (anOnScreenObject = [enumerator nextObject])
    {
        [anOnScreenObject draw];
        if (theControllerData.showOnScreenObjectLabel) [anOnScreenObject
drawOnScreenObjectLabel];
    }
}




- (void) draw
{
    if ((*theControllerDataPtr).showControlRects)
    {
        ...
   }

    if ((*theControllerDataPtr).showObject)
    {
        transform = [NSAffineTransform transform];
        [transform translateXBy:enclosingRectOfObject.origin.x
                            yBy:enclosingRectOfObject.origin.y];
        [transform rotateByRadians:rotation];

        eraseTransform = [transform retain];

        {
            NSBezierPath *transformedPath = [transform
transformBezierPath:bisPolygonPath];

            [objectColor set];

            // transformedPath = [self calculatePolygon];

            // transformedPath = nil;

            /*
            [(*theControllerDataPtr).circlesScreenSaverView
outputObject:transformedPath

toFile:@"transformedPath.txt"

withFormat:@"transformedPath = %@\n"

andTag:[dateFormatter stringFromDate:[NSDate date]]];
             */


            // if (YES) {[transformedPath fill];} else {[transformedPath
stroke];}
            if (fillOrStroke) {[transformedPath fill];} else
{[transformedPath stroke];}
        }
    }
}

And here is a method added to BISPolygon.m for testing specific troubled
polygons (uncomment

// transformedPath = [self calculatePolygon];

in the above -draw method):

 // this one crashes
 - (NSBezierPath *)calculatePolygon
{
    NSBezierPath *path = [NSBezierPath bezierPath];
    [path moveToPoint:NSMakePoint(127.761421, 227.956528)];
    [path lineToPoint:NSMakePoint(96.961540, 275.849915)];
    [path lineToPoint:NSMakePoint(115.441422, 333.059204)];
    [path lineToPoint:NSMakePoint(169.285324, 356.504639)];
    [path lineToPoint:NSMakePoint(217.947693, 328.531311)];
    [path lineToPoint:NSMakePoint(224.784775, 270.203705)];
    [path lineToPoint:NSMakePoint(184.648117, 225.443726)];
    [path lineToPoint:NSMakePoint(127.761436, 227.956512)];
    [path closePath];

    return path;
}

Here is a crash report showing the crash within -stroke called from -draw

Host Name:      IntelMac2
Date/Time:      2006-06-27 04:03:25.189 -0600
OS Version:     10.4.4 (Build 8G1171)
Report Version: 4

Command: ScreenSaverEngine
Path:
/System/Library/Frameworks/ScreenSaver.framework/Resources/ScreenSaverEngine
.app/Contents/MacOS/ScreenSaverEngine
Parent:  loginwindow [124]

Version:        1.5 (1.5)
Build Version:  60
Project Name:   ScreenSaver
Source Version: 1220300

PID:    4779
Thread: 0

Exception:  EXC_BAD_ACCESS (0x0001)
Codes:      KERN_INVALID_ADDRESS (0x0001) at 0xc000388c

Thread 0 Crashed:
0   com.apple.CoreGraphics             0x903b635f draw_line + 5035
1   com.apple.CoreGraphics             0x903b4ef3 line_to + 1082
2   com.apple.CoreGraphics             0x903b47fc aa_line_render + 484
3   libRIP.A.dylib                     0x943b2597 ripr_Coverage + 1020
4   libRIP.A.dylib                     0x943b200b ripc_Render + 443
5   libRIP.A.dylib                     0x943bd070 ripc_DrawPath + 300
6   com.apple.CoreGraphics             0x9038cff2 CGContextDrawPath + 169
7   com.apple.CoreGraphics             0x903b426b CGContextStrokePath + 25
8   com.apple.AppKit                   0x9348a3ee
-[NSBezierPath(NSBezierPathDevicePrimitives) _doUserPathWithOp:inContext:] +
264
9   com.apple.AppKit                   0x934cc216 -[NSBezierPath stroke] +
246
10  ...ersearch.CirclesScreenSaver     0x0027e4de -[BISPolygon draw] + 528
(BISPolygon.m:139)
11  ...ersearch.CirclesScreenSaver     0x00277eed -[CirclesScreenSaverView
drawRect:] + 2166 (CirclesScreenSaverView.m:376)
12  ...ersearch.CirclesScreenSaver     0x00281e4b -[BenchmarkCirclesSSView
drawRect:] + 98 (BenchmarkCirclesSSView.m:37)
13  com.apple.AppKit                   0x933eea97 -[NSView _drawRect:clip:]
+ 3228
14  com.apple.AppKit                   0x933edaf1 -[NSView
_recursiveDisplayAllDirtyWithLockFocus:visRect:] + 614
15  com.apple.AppKit                   0x933ecb59 -[NSView
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRect
ForView:topView:] + 217
16  com.apple.AppKit                   0x933ed727 -[NSView
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRect
ForView:topView:] + 3239
17  com.apple.AppKit                   0x934cbcfd -[NSNextStepFrame
_recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRect
ForView:topView:] + 601
18  com.apple.AppKit                   0x933eba4c -[NSView
_displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 523
19  com.apple.AppKit                   0x933eb37c -[NSView displayIfNeeded]
+ 439
20  com.apple.AppKit                   0x933eb11e -[NSWindow
displayIfNeeded] + 168
21  com.apple.AppKit                   0x9343b3cc _handleWindowNeedsDisplay
+ 206
22  com.apple.CoreFoundation           0x90823419 __CFRunLoopDoObservers +
342
23  com.apple.CoreFoundation           0x908224bb CFRunLoopRunSpecific + 827
24  com.apple.CoreFoundation           0x90822179 CFRunLoopRunInMode + 61
25  com.apple.HIToolbox                0x92ecf8e0 RunCurrentEventLoopInMode
+ 285
26  com.apple.HIToolbox                0x92ecefe7 ReceiveNextEventCommon +
385
27  com.apple.HIToolbox                0x92ecee3e
BlockUntilNextEventMatchingListInMode + 81
28  com.apple.AppKit                   0x9336fc11 _DPSNextEvent + 576
29  com.apple.AppKit                   0x9336f7fe -[NSApplication
nextEventMatchingMask:untilDate:inMode:dequeue:] + 137
30  com.apple.ScreenSaver.Engine       0x00004cce 0x1000 + 15566
31  com.apple.AppKit                   0x93369583 -[NSApplication run] + 512
32  com.apple.ScreenSaver.Engine       0x00002721 0x1000 + 5921
33  com.apple.ScreenSaver.Engine       0x000024aa 0x1000 + 5290
34  com.apple.ScreenSaver.Engine       0x000023c5 0x1000 + 5061

When I first saw these crashes, they were infrequent (one every 30 - 60
minutes), but always -stroke, never -fill. I changed

if (fillOrStroke) {[transformedPath fill];} else {[transformedPath stroke];}

to

if (YES) {[transformedPath fill];} else {[transformedPath stroke];}

to test if a filled polygon would crash; filled polygons always draw. When I
deliberately release transformedPath before the above line, the crash report
shows a released object, not an object being drawn:

Thread 0 Crashed:
0   libobjc.A.dylib                    0x90a559c1 _objc_error + 86
1   libobjc.A.dylib                    0x90a559f8 __objc_error + 45
2   libobjc.A.dylib                    0x90a54060 _freedHandler + 53
3   ...ersearch.CirclesScreenSaver     0x0027e4db -[BISPolygon draw] + 489
(BISPolygon.m:141)
4   ...ersearch.CirclesScreenSaver     0x00277f12 -[CirclesScreenSaverView
drawRect:] + 2139 (CirclesScreenSaverView.m:371)
5   ...ersearch.CirclesScreenSaver     0x00281e48 -[BenchmarkCirclesSSView
drawRect:] + 98 (BenchmarkCirclesSSView.m:37)

Suspecting that I was somehow passing a troubled polygon, I inserted code to
output the polygon to a file. At the time of crash, the file contained the
polygon that was passed to stroke. When I stroke this polygon in a test
application containing a custom NSView, the polygon draws. When I stroke
this polygon within -[BISPolygon draw], crash occurs. If I fill the polygon
within  -[BISPolygon draw], fill occurs.

I confirmed that the view's bounds are unchanged by requesting notification
and using printf within my note handler to record bounds changes. From
-[CirclesScreenSaverView initWithFrame:isPreview:]

        [[NSNotificationCenter defaultCenter] addObserver:self

selector:@selector(noteBoundsChanged:)

name:NSViewBoundsDidChangeNotification
                                                   object:nil];
        [self setPostsBoundsChangedNotifications:YES];

        // [self setBounds:[self bounds]];


When I uncomment the last line, a bounds change is noted; with the last line
commented out, no bounds changes are noted.

So what is happening here? Thanks.




 _______________________________________________
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: Arbitrary polygons crash -[NSBezierPath stroke]
      • From: Uli Kusterer <email@hidden>
  • Prev by Date: Re: Beginner Question About CustomView, -drawRect: and Plotting Data.
  • Next by Date: Re: Beginner Question About CustomView, -drawRect: and Plotting Data.
  • Previous by thread: Re: NSFindAndReplace
  • Next by thread: Re: Arbitrary polygons crash -[NSBezierPath stroke]
  • Index(es):
    • Date
    • Thread