Canceling NSSavePanel Hang App


Sandor Szatmari
 

Ran into an interesting issue today…
Mac app
Xcode 9.4.1, 32bit, 10.12 SDK, 10.6 Deployment Target
non-sandboxed app

I am opening an NSSavePanel to allow a user to save the results of a report that is to be generated.

// Creating the save panel
NSSavePanel* savePanel = [NSSavePanel savePanel];
[savePanel setTitle:[NSString stringWithFormat:@"Export %@ Summary Data for %@", [self selectedReport], customerName]];

Opening the NSSavePanel using -runModal
savePanelUserAction = [savePanel runModal];

If the user enters a filename and clicks continue the save dialog closes, the report is generated, and the file is written to disk at the selected location.
if (savePanelUserAction == NSFileHandlingPanelOKButton)
[NSThread detachNewThreadSelector:@selector(createSummary:) toTarget:self withObject:[[savePanel URL] path]];

If the user clicks cancel, the program hangs. It hangs so badly that I have to go to the System Force-Quit dialog in order to fully terminate the app.
(i.e. Clicking stop program in Xcode does not fully terminate the app)
else
{
// Program hangs
}

I have checked that the NSSavePanel is being opened from the main thread.
I have included interesting backtraces below that are present if I stop the app in the de

Sandor

Thread 1 Queue : com.apple.main-thread (serial)
#0 0xa73d423e in kevent_id ()
#1 0x003305a6 in _dispatch_kq_poll ()
#2 0x00331141 in _dispatch_event_loop_wait_for_ownership ()
#3 0x00327b80 in _dispatch_sync_wait ()
#4 0x0031d500 in _dispatch_sync_f_slow ()
#5 0x0030f6d1 in dispatch_barrier_sync_f ()
#6 0x00316bf3 in dispatch_barrier_sync ()
#7 0x9387ebd4 in _VolumeObserverInvalidate ()
#8 0xa04ee78e in TSystemNotificationTask::~TSystemNotificationTask() ()
#9 0xa04ee818 in TSystemNotificationTask::FinalizeSystemNotificationTask() ()
#10 0xa04dda71 in NodeContextClose ()
#11 0x0afc689a in TFENode::Finalize() ()
#12 0x0b127290 in +[FIFinderViewGutsController finalizeCounted] ()
#13 0x0b127366 in __45+[FIFinderViewGutsController finalizeCounted]_block_invoke ()
#14 0x003167af in _dispatch_call_block_and_release ()
#15 0x0030e94d in _dispatch_client_callout ()
#16 0x0031ae6c in _dispatch_main_queue_callback_4CF ()
#17 0x937bb2ae in __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ ()
#18 0x9377ecf4 in __CFRunLoopRun ()
#19 0x9377dbd1 in CFRunLoopRunSpecific ()
#20 0x9377d93a in CFRunLoopRunInMode ()
#21 0x92d7b37b in RunCurrentEventLoopInMode ()
#22 0x92d7b0a2 in ReceiveNextEventCommon ()
#23 0x92d7ad7b in _BlockUntilNextEventMatchingListInModeWithFilter ()
#24 0x9137aafd in _DPSNextEvent ()
#25 0x91aece90 in -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] ()
#26 0x91aec35d in -[NSApplication(NSEvent) nextEventMatchingMask:untilDate:inMode:dequeue:] ()
#27 0x9136fa4d in -[NSApplication run] ()
#28 0x91341b0a in NSApplicationMain ()
#29 0x000026bc in main at /Users/username/repo/AppName/main.m:13
#30 0x00002685 in start ()
Enqueued from TBrowserViewDataSource (Thread 14) Queue : TBrowserViewDataSource (serial)
#0 0x0033f4dc in _dispatch_introspection_queue_item_enqueue ()
#1 0x00325cf8 in _dispatch_queue_push ()
#2 0x00323230 in _dispatch_continuation_push ()
#3 0x0032259b in _dispatch_continuation_async ()
#4 0x00316173 in dispatch_async ()
#5 0x0b1272f6 in +[FIFinderViewGutsController finalizeCounted] ()
#6 0x0b1aa3af in -[FI_TBrowserViewDataSource dealloc] ()
#7 0xa67a09f9 in objc_object::sidetable_release(bool) ()
#8 0xa679e2d0 in -[NSObject release] ()
#9 0x0b1aa762 in __destroy_helper_block_ ()
#10 0xa72c6b75 in _Block_release ()
#11 0x0030e94d in _dispatch_client_callout ()
#12 0x00324d3a in _dispatch_queue_serial_drain ()
#13 0x003162e2 in _dispatch_queue_invoke ()
#14 0x0032646e in _dispatch_root_queue_drain_deferred_wlh ()
#15 0x0032b4bb in _dispatch_workloop_worker_thread ()
#16 0x00381601 in _pthread_wqthread ()
#17 0x0038121e in start_wqthread ()
Enqueued from com.apple.main-thread (Thread 1) Queue : com.apple.main-thread (serial)
#0 0x0033f4dc in _dispatch_introspection_queue_item_enqueue ()
#1 0x00325cf8 in _dispatch_queue_push ()
#2 0x00323230 in _dispatch_continuation_push ()
#3 0x0032259b in _dispatch_continuation_async ()
#4 0x00316173 in dispatch_async ()
#5 0x0b1aa460 in -[FI_TBrowserViewDataSource aboutToTearDown] ()
#6 0x0b1e0aa5 in -[FI_TBrowserContainerController destroyBrowserView:] ()
#7 0x0b1e3ed4 in -[FIContainerController destroyBrowserView:] ()
#8 0x0b1e06c6 in -[FI_TBrowserContainerController aboutToTearDown] ()
#9 0x0b1e3f3b in -[FIContainerController aboutToTearDown] ()
#10 0xa67a0bda in -[NSObject performSelector:] ()
#11 0x0b042f47 in AboutToTearDownViewController(NSViewController*) ()
#12 0x0b07a83c in -[FI_TBrowserContentViewController aboutToTearDown] ()
#13 0xa67a0bda in -[NSObject performSelector:] ()
#14 0x0b042f47 in AboutToTearDownViewController(NSViewController*) ()
#15 0x0b1293f0 in -[FIFinderViewGutsController prepareToHide] ()
#16 0x0b12996f in -[FIFinderViewGutsController windowOrderedOut] ()
#17 0x0b13486f in -[FIFinderView windowOrderedOut] ()
#18 0x91e3ffe5 in -[NSNavFinderViewFileBrowser windowOrderedOut] ()
#19 0x91a4df5e in -[NSSavePanel _navViewWindowOrderedOut] ()
#20 0x91a4dfc5 in -[NSSavePanel orderOut:] ()
#21 0x91a5bffa in -[NSSavePanel _didEndSheet:returnCode:contextInfo:] ()
#22 0x91c27b17 in NSWindowEndWindowModalSession ()
#23 0x915acaf6 in -[NSWindow _endWindowBlockingModalSession:returnCode:] ()
#24 0x915aca86 in -[NSWindow endSheet:returnCode:] ()
#25 0x915f7367 in -[NSApplication endSheet:returnCode:] ()
#26 0x91a5e2cb in -[NSSavePanel _dismissWindowWithReturnCode:willRunSeamlessOpening:] ()
#27 0x91a5e2f1 in -[NSSavePanel _cancelAndClose] ()
#28 0x91a5e933 in -[NSSavePanel cancel:] ()
#29 0xa67a0c1c in -[NSObject performSelector:withObject:] ()
#30 0x91aeeca9 in __49-[NSApplication(NSResponder) sendAction:to:from:]_block_invoke ()
#31 0x91aeec4d in __NS_ACTIVITY_PERFORM_EXCEPTION_SAFE ()
#32 0x91aeeb4f in -[NSApplication(NSResponder) sendAction:to:from:] ()
#33 0x9159eda8 in -[NSControl sendAction:to:] ()
#34 0x9159ecc7 in __26-[NSCell _sendActionFrom:]_block_invoke ()
#35 0x917e5009 in __NS_ACTIVITY_PERFORM_EXCEPTION_SAFE ()
#36 0x9159ec11 in -[NSCell _sendActionFrom:] ()
#37 0x915dd6cb in -[NSButtonCell _sendActionFrom:] ()
#38 0x917e6e2c in __48-[NSCell trackMouse:inRect:ofView:untilMouseUp:]_block_invoke.1099 ()
#39 0x917e5009 in __NS_ACTIVITY_PERFORM_EXCEPTION_SAFE ()
#40 0x9159d58d in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] ()
#41 0x915dd420 in -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] ()
#42 0x9159bff4 in -[NSControl mouseDown:] ()
#43 0x91c922b4 in -[NSWindow(NSEventRouting) _handleMouseDownEvent:isDelayedEvent:] ()
#44 0x91c9024f in -[NSWindow(NSEventRouting) _reallySendEvent:isDelayedEvent:] ()
#45 0x91c8e4c0 in -[NSWindow(NSEventRouting) sendEvent:] ()
#46 0x91aeb2d5 in -[NSApplication(NSEvent) sendEvent:] ()
#47 0x9136fa98 in -[NSApplication run] ()
#48 0x91341b0a in NSApplicationMain ()
#49 0x000026bc in main at /Users/username/repo/AppName/main.m:13
#50 0x00002685 in start ()


// Other threads that seemed interesting, but could be misleading???

Thread 2 Queue : com.apple.CFVolumeObserver.0x6af670 (serial)
#0 0xa73d242a in __getattrlist ()
#1 0x9ffa770f in volumePropertyProviderPrepareValues(__CFURL const*, __FileCache*, __CFString const* const*, void const**, long, void const*, __CFError**) ()
#2 0x9ffa1ebd in prepareValuesForBitmap(__CFURL const*, __FileCache*, _FilePropertyBitmap*, __CFError**) ()
#3 0x9ff9f858 in _FSURLCopyResourcePropertyForKeyInternal(__CFURL const*, __CFString const*, void*, void*, __CFError**, unsigned char) ()
#4 0x9ff9f779 in _FSURLCopyResourcePropertyForKey ()
#5 0x93765cd0 in CFURLCopyResourcePropertyForKey ()
#6 0x937dfaf6 in _VolumeObserverDiskAppearedCallback ()
#7 0x9513f6ab in _DADispatchCallback ()
#8 0x9513f439 in _DASessionCallback ()
#9 0x9513f304 in __DASessionSetDispatchQueue_block_invoke_2 ()
#10 0x0030e94d in _dispatch_client_callout ()
#11 0x00323464 in _dispatch_continuation_pop ()
#12 0x00310eba in _dispatch_source_invoke ()
#13 0x00324b73 in _dispatch_queue_serial_drain ()
#14 0x003162e2 in _dispatch_queue_invoke ()
#15 0x0032646e in _dispatch_root_queue_drain_deferred_wlh ()
#16 0x0032b4bb in _dispatch_workloop_worker_thread ()
#17 0x00381601 in _pthread_wqthread ()
#18 0x0038121e in start_wqthread ()


Thread 10 Queue : com.apple.CFVolumeObserver.0x6ac5d0 (serial)
#0 0xa73d242a in __getattrlist ()
#1 0x9ffa770f in volumePropertyProviderPrepareValues(__CFURL const*, __FileCache*, __CFString const* const*, void const**, long, void const*, __CFError**) ()
#2 0x9ffa1ebd in prepareValuesForBitmap(__CFURL const*, __FileCache*, _FilePropertyBitmap*, __CFError**) ()
#3 0x9ff9f858 in _FSURLCopyResourcePropertyForKeyInternal(__CFURL const*, __CFString const*, void*, void*, __CFError**, unsigned char) ()
#4 0x9ff9f779 in _FSURLCopyResourcePropertyForKey ()
#5 0x93765cd0 in CFURLCopyResourcePropertyForKey ()
#6 0x937dfaf6 in _VolumeObserverDiskAppearedCallback ()
#7 0x9513f6ab in _DADispatchCallback ()
#8 0x9513f439 in _DASessionCallback ()
#9 0x9513f304 in __DASessionSetDispatchQueue_block_invoke_2 ()
#10 0x0030e94d in _dispatch_client_callout ()
#11 0x00323464 in _dispatch_continuation_pop ()
#12 0x00310eba in _dispatch_source_invoke ()
#13 0x00324b73 in _dispatch_queue_serial_drain ()
#14 0x003162e2 in _dispatch_queue_invoke ()
#15 0x0032646e in _dispatch_root_queue_drain_deferred_wlh ()
#16 0x0032b4bb in _dispatch_workloop_worker_thread ()
#17 0x00381601 in _pthread_wqthread ()
#18 0x0038121e in start_wqthread ()

Join cocoa@apple-dev.groups.io to automatically receive all group messages.