In between midnight summer nights and dark winter days

Mysterious window server hangs Sun, Sep 16 2007 17:50

I was working on a very bare-bones Cocoa application on friday, and stumbled across a most annoying window server bug. The application I was working on creates windows on demand, but without using NIBs. Instead, I used the code below to create a new window:

[[NSWindow alloc] initWithContentRect:rect styleMask:(NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask) backing:NSBackingStoreRetained defer:YES];

Once the window is ordered front and becomes visible, the entire window server hangs. The Mac stops responding to keyboard input, with only the pointer remaining functional. That is, functional in the sense that it continues to move, but you can't actually do anything.

So, what is the cause of this bug? To my luck, I was still able to log in to my computer from the command line. Everything appeared normal - no excessive CPU use, and no particular memory demand. Using the 'sample' utility and gdb, I discovered that my application was hung with the following backtrace:

_displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:]
-[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity...
-[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:...
-[NSView _drawRect:clip:]
-[NSThemeFrame drawRect:]
-[NSFrameView drawRect:]
-[NSThemeFrame drawFrame:]
-[NSThemeFrame _drawFrameInterior:clip:]
-[NSThemeFrame _drawTitleBar:]
Draw3PartImage
-[NSImage _compositeFlipped:atPoint:fromRect:operation:fraction:]
-[NSImage _compositeFlipped:inRect:fromRect:operation:fraction:]
-[NSImage drawInRect:fromRect:operation:fraction:]
-[NSBitmapImageRep _drawFromRect:toRect:operation:alpha:compositing:flipped:ignoreContext:]
CGContextDrawImage
ripc_DrawImage
ripc_RenderImage
ripl_BltImage
ripd_Lock
CGSDeviceLock
_CGSLockWindow
_CGSSynchronizeWindowBackingStore
mach_msg_trap
mach_msg_trap

Notice the CGSSynchronizeWindowBackingStore call at the very end? I did too. It looks like the window server gets deadlocked in some way. If you wait long enough, the window server will come back in brief bursts, allowing you to give input to the application (for instance to quit it). The application can also be killed, but you won't see a response for the next thirty-or-so seconds before the window server collects its senses again.

Going back to my code, after commenting out nearly every part of the very small app, I narrowed it down to the way the window is created. More specifically, the problem is that I was attempting to create a so-called "retained" window, rather than a "buffered" window. Substituting NSBackingStoreRetained for NSBackingStoreBuffered completely solved my problems. (I had no good reason to choose one over the other when I wrote the code, so I picked the backing store constant more or less at random.)

A small example is available for download here. It creates a 128x128 sized window and displays it three seconds after being launched. It exhibits the bug on my MacBook Pro running 10.4.10. To experience the bug, you will need to move the window so that parts of it will be obscured by another application's window(s), or by the Dock's application switcher (Command-tab). You should be able to get out of the app by hitting Command-Q repeatedly, until the window server sees fit to respond. To be on the safe side, save your work before running the app.



First post! Next: FolderGlance and Screen Sieve now also on Leopard!

About me
My name is Daniel Stødle. I live in Tromsø, Norway, at 69.66° North. By day, I work as a researcher at the Northern Research Institute in Norway; by night, I run my company SCSC. I do most of my development on and for Mac OS X. My research is geared towards interaction with and visualization of geospatial data. Read more on my personal page.

Software

Contact me
E-mail: daniel@scsc.no

Recent posts


2011
Jul 28: Running iTunes in a debugger (gdb)
Jul 25: The /Volumes/MobileBackups directory
Jul 20: FolderGlance 3.0.1 supports Lion
Mar 03: Quick tip: Speeding up Xcode compilations
Mar 02: FolderGlance 3.0
Jan 07: Making Universal Back Button work on 10.6.5 and later

2010
Sep 03: Creating pthreads in C++ using pointers to member functions
May 31: Quickly open URLs in Terminal
May 31: Snow Leopard and automatically submitted Crash Reports
May 27: Universal Back Button released for Mac OS X
May 22: The 22 Megapixel Laptop
Feb 09: FolderGlance on MacUpdate Promo

2009
Sep 28: FolderGlance 2.5.3 is out
Sep 21: FolderGlance 2.5.1 adds features and fixes bugs
Sep 16: FolderGlance 2.5 released!
Sep 10: Intriguing: Snow Leopard ships with the iPhone's multi-touch API built-in
Sep 03: FolderGlance and Snow Leopard
Mar 15: Fixing Keynote '08 and '09 to work with the Scripting Bridge
Feb 26: A website in an image
Feb 09: Display wall multi-touch

2008
Feb 19: Spaces.. Spaces.. Spaces.. retires
Feb 08: How-to: Reverse engineering the Dock to fix Spaces
Jan 25: Interacting with wall-sized displays

2007
Dec 20: Interesting Finder bug
Dec 06: Developing applications for the iPod touch (and the iPhone)
Nov 15: Spaces.. Spaces.. Spaces.. and 10.5.1
Nov 15: Thread creation using pthread_create() on Leopard
Nov 13: Spaces.. Spaces.. Spaces..
Nov 07: FolderGlance, Leopard and the More... menu
Nov 06: FolderGlance and Screen Sieve now also on Leopard!
Sep 16: Mysterious window server hangs

Archive
2007
2008
2009
2010
2011

RSS feed
RSS

Links
SCSC
Blog frontpage