NSWorkspace setIcon:forFile:options: crashes - cocoa

I am facing crash sometimes on [NSWorkspace setIcon:forFile:options:] API.
any help is appreciated.
here is crash stack,
0 libsystem_kernel.dylib 0x00007fff85bfbe56 __semwait_signal_nocancel + 10
1 libsystem_c.dylib 0x00007fff8c04818b nanosleep$NOCANCEL + 139
2 libsystem_c.dylib 0x00007fff8bfe7c78 usleep$NOCANCEL + 53
3 libsystem_c.dylib 0x00007fff8bfe7aa6 abort + 187
4 libsystem_c.dylib 0x00007fff8c04684c free + 389
5 com.apple.CoreServices.CarbonCore 0x00007fff8df7aaf7 CSMemDisposePtr + 23
6 com.apple.CoreServices.CarbonCore 0x00007fff8df7aaba CSMemDisposeHandle + 79
7 com.apple.CoreServices.CarbonCore 0x00007fff8df7c355 DisposeHandle + 9
8 com.apple.AppKit 0x00007fff90356598 -[NSWorkspace setIcon:forFile:options:] + 566
Here is code,
static NSImage *FolderIcon = nil;
if(!FolderIcon) {
FolderIcon = [[NSImage imageNamed:#"xxx.icns"] retain];
}
if(![[NSWorkspace sharedWorkspace] setIcon: FolderIcon
forFile:Path
options:0]) {
NSLog(#"error");
}
I am using static icon, so I don't think possibility of dangling pointer, Also I checked if we pass file path which does not exists then it return "NO". But it is not crashing.
This is rarely re-producible.. will paste errors once it re-produce

You should not call -setIcon:forFile:options: from multiple thread at a time.
From Documentation:
It is safe to call this method from any of your app’s threads, but you
must call it from only one thread at a time.

Related

xamarin error : NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application

I am trying to reorganize an old application written in Xamarin. The application gives the following error without opening the application in the simulator. Can you help me?
Objective-C exception thrown. Name: NSInternalInconsistencyException Reason: Application windows are expected to have a root view controller at the end of application launch
Native stack trace:
0 CoreFoundation 0x00007fff20421af6 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff20177e78 objc_exception_throw + 48
2 CoreFoundation 0x00007fff2042191f +[NSException raise:format:] + 0
3 Foundation 0x00007fff2077156a -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
4 UIKitCore 0x00007fff2469a8fc -[UIApplication _runWithMainScene:transitionContext:completion:] + 2148
5 UIKitCore 0x00007fff23cc36f7 -[_UISceneLifecycleMultiplexer completeApplicationLaunchWithFBSScene:transitionContext:] + 122
6 UIKitCore 0x00007fff24251d1e _UIScenePerformActionsWithLifecycleActionMask + 88
7 UIKitCore 0x00007fff23cc4206 __101-[_UISceneLifecycleMultiplexer _evalTransitionToSettings:fromSettings:forceExit:withTransitionStore:]_block_invoke + 198
8 UIKitCore 0x00007fff23cc3cca -[_UISceneLifecycleMultiplexer _performBlock:withApplicationOfDeactivationReasons:fromReasons:] + 474
......
enter image description here
iOS9 requires all the Window must have a rootViewController, you should edit AppDelegate like this:
public override bool FinishedLaunching (UIApplication application, NSDictionary launchOptions)
{
// Override point for customization after application launch.
// If not required for your application you can safely delete this method
var indexVC = new IndexViewController ();
window = new UIWindow ((CGRect)UIScreen.MainScreen.Bounds);
window.RootViewController = indexVC;
window.MakeKeyAndVisible ();
return true;
}
you can refer to this page for more details.
There are some changes since ios9, you can refer to this and this page

How to show my source code in stack trace for Xamarin iOS app?

My Xamarin iOS app crashes with error "unrecognized selector sent to instance...", but neither the stack trace nor the call stack has any useful information of where could be the problem in my source code. I'm using Visual Studio for Mac, and the app is running on the iOS simulator. Are there any options that need to be enabled in order to show my source code in the stack trace?
Unhandled Exception:
Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[NSObject doesNotRecognizeSelector]: unrecognized selector sent to instance 0x600000016d80
Native stack trace:
0 CoreFoundation 0x000000010579e12b __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00000001066d8f41 objc_exception_throw + 48
2 CoreFoundation 0x000000010581f024 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x0000000105720f78 ___forwarding___ + 1432
4 CoreFoundation 0x0000000105720958 _CF_forwarding_prep_0 + 120
5 Foundation 0x0000000103997f35 __NSFireDelayedPerform + 409
6 CoreFoundation 0x000000010572e174 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
7 CoreFoundation 0x000000010572de32 __CFRunLoopDoTimer + 1026
8 CoreFoundation 0x000000010572d9ea __CFRunLoopDoTimers + 266
9 CoreFoundation 0x0000000105725404 __CFRunLoopRun + 2308
10 CoreFoundation 0x0000000105724889 CFRunLoopRunSpecific + 409
11 GraphicsServices 0x0000000108cfb9c6 GSEventRunModal + 62
12 UIKit 0x00000001013375d6 UIApplicationMain + 159
13 ??? 0x00000001179fbe98 0x0 + 4691312280
14 ??? 0x00000001179fbac3 0x0 + 4691311299
Update:
The problem seems related to .dSYM files not being generated for the simulator.
This is what I add to my Application.cs class to better see exception information:
static void Main(string[] args)
{
#if DEBUG
try
{
#endif
UIApplication.Main(args, null, "AppDelegate");
#if DEBUG
}
catch (Exception ex)
{
var msg = ex.Message;
var temp = ex.StackTrace;
if(System.Diagnostics.Debugger.IsAttached)
System.Diagnostics.Debugger.Break();
throw;
}
#endif
}
You can trace inside xamarin source code. Details specified in Microsoft documentation.
Also you can get more diagnostic details during debugging by changing Xamarin options as specified in Xamarin forums.

How to update an NSTextView while user is scrolling (without crashing)

I'm using an NSTextView to display the result of a long search, where lines are added as they are found by a background thread using
[self performSelectorOnMainThread: #selector(addMatch:)
withObject:options waitUntilDone:TRUE];
As the update routine I have
-(void)addMatch:(NSDictionary*)options{
...
NSTextStorage* store = [textView textStorage];
[store beginEditing];
[store appendAttributedString:text];
...
[store endEditing];
}
This works fine, until the user scrolls through the matches as they are being updated, at which point there's an exception
-[NSLayoutManager _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] *** attempted layout while textStorage is editing. It is not valid to
cause the layoutManager to do layout while the textStorage is editing
(ie the textStorage has been sent a beginEditing message without a
matching endEditing.)
within a layout call:
0 CoreFoundation 0x00007fff92ea364c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8acd16de objc_exception_throw + 43
2 CoreFoundation 0x00007fff92ea34fd +[NSException raise:format:] + 205
3 UIFoundation 0x00007fff8fe4fbc1 -[NSLayoutManager(NSPrivate) _fillLayoutHoleForCharacterRange:desiredNumberOfLines:isSoft:] + 641
4 UIFoundation 0x00007fff8fe5970c _NSFastFillAllLayoutHolesForGlyphRange + 1493
5 UIFoundation 0x00007fff8fda8821 -[NSLayoutManager lineFragmentRectForGlyphAtIndex:effectiveRange:] + 39
6 AppKit 0x00007fff8ef3cb02 -[NSTextView _extendedGlyphRangeForRange:maxGlyphIndex:drawingToScreen:] + 478
7 AppKit 0x00007fff8ef3ba97 -[NSTextView drawRect:] + 1832
8 AppKit 0x00007fff8eed9a09 -[NSView(NSInternal) _recursive:displayRectIgnoringOpacity:inGraphicsContext:CGContext:topView:shouldChangeFontReferenceColor:] + 1186
9 AppKit 0x00007fff8eed9458 __46-[NSView(NSLayerKitGlue) drawLayer:inContext:]_block_invoke + 218
10 AppKit 0x00007fff8eed91f1 -[NSView(NSLayerKitGlue) _drawViewBackingLayer:inContext:drawingHandler:] + 2407
11 AppKit 0x00007fff8eed8873 -[NSView(NSLayerKitGlue) drawLayer:inContext:] + 108
12 AppKit 0x00007fff8efaafd2 -[NSTextView drawLayer:inContext:] + 179
13 AppKit 0x00007fff8ef22f76 -[_NSBackingLayerContents drawLayer:inContext:] + 145
14 QuartzCore 0x00007fff9337c177 -[CALayer drawInContext:] + 119
15 AppKit 0x00007fff8ef22aae -[_NSTiledLayer drawTile:inContext:] + 625
16 AppKit 0x00007fff8ef227df -[_NSTiledLayerContents drawLayer:inContext:] + 169
17 QuartzCore 0x00007fff9337c177 -[CALayer drawInContext:] + 119
18 AppKit 0x00007fff8f6efd64 -[NSTileLayer drawInContext:] + 169
19 QuartzCore 0x00007fff9337b153 CABackingStoreUpdate_ + 3306
20 QuartzCore 0x00007fff9337a463 ___ZN2CA5Layer8display_Ev_block_invoke + 59
21 QuartzCore 0x00007fff9337a41f x_blame_allocations + 81
22 QuartzCore 0x00007fff93379f1c _ZN2CA5Layer8display_Ev + 1546
23 AppKit 0x00007fff8ef226ed -[NSTileLayer display] + 119
24 AppKit 0x00007fff8ef1ec34 -[_NSTiledLayerContents update:] + 5688
25 AppKit 0x00007fff8ef1d337 -[_NSTiledLayer display] + 375
26 QuartzCore 0x00007fff93379641 _ZN2CA5Layer17display_if_neededEPNS_11TransactionE + 603
27 QuartzCore 0x00007fff93378d7d _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 35
28 QuartzCore 0x00007fff9337850e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
29 QuartzCore 0x00007fff93378164 _ZN2CA11Transaction6commitEv + 390
30 QuartzCore 0x00007fff93388f55 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 71
31 CoreFoundation 0x00007fff92dc0d87 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
32 CoreFoundation 0x00007fff92dc0ce0 __CFRunLoopDoObservers + 368
33 CoreFoundation 0x00007fff92db2f1a __CFRunLoopRun + 1178
34 CoreFoundation 0x00007fff92db2838 CFRunLoopRunSpecific + 296
35 UIFoundation 0x00007fff8fdfe744 -[NSHTMLReader _loadUsingWebKit] + 2097
36 UIFoundation 0x00007fff8fdffb55 -[NSHTMLReader attributedString] + 22
37 UIFoundation 0x00007fff8fe12cca _NSReadAttributedStringFromURLOrData + 10543
38 UIFoundation 0x00007fff8fe10306 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 115
What is wrong, given that everything is between beginEditing and endEditing?
From the stack trace (which is not complete), it looks like a run loop source is firing at an inopportune moment.
NSAttributedString uses WebKit to parse HTML. WebKit sometimes runs the run loop. For the general case, it may need to fetch resources from the network to render properly. Since that takes time, it runs the run loop to wait for the result and process other things at the same time.
One of the other run loop sources seems to be a Core Animation source to do the next step in some animation (scrolling the text view, presumably).
You didn't show all of the code between beginEditing and endEditing. I suspect you have constructed an NSAttributedString from HTML or data fetched from a URL in between those two places. That allows the Core Animation run loop source to fire. That asks the text view to draw, which asks its layout manager to lay out the text. This is occurring after beginEditing but before endEditing, which is the cause for the exception.
So, try reordering your code to construct all NSAttributedStrings before beginEditing.
And file a bug with Apple. In my opinion, when NSAttributeString uses WebKit to render HTML, it needs to make WebKit use a private run loop mode so no other sources can fire. They may prefer a different solution, but the bug is real.
As far as I can tell, there's no fix for this. An alternative that works is storing the matches as attributed strings in an array, and using an NSTableView to show the matches by setting the textField.attributedStringValue (calling reloadData every time you add a new match); something like this (where matchContent is an NSMutableArray):
-(void)addMatch:(NSDictionary*)options{
...
[matchContent addObject:text];
[resultTableView reloadData];
}
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return matchContent.count;
}
- (NSView *)tableView:(NSTableView *)tableView
viewForTableColumn:(NSTableColumn *)tableColumn
row:(NSInteger)row {
NSTableCellView *result = [tableView makeViewWithIdentifier:#"MyView" owner:self];
result.textField.attributedStringValue = [matchContent objectAtIndex:row];
return result;
}
If the result is multi-line, you may also need to check the autoresizing mask of the cell/text field, and return the row height for the table view using the attributed string's boundingRectWithSize method.

AVMutableVideoComposition - CoreAnimation: warning, deleted thread with uncommitted CATransaction

I am working on some basic video compositions using AVMutableComposition - currently a video layer (AVMutableVideoComposition) with a text layer (CATextLayer).
It all looks ok but when I let it export via "AVMutableComposition exportAsynchronouslyWithCompletionHandler " it goes off and completes but returns this error:
CoreAnimation: warning, deleted thread with uncommitted CATransaction; created by:
0 QuartzCore 0x00007fff8a106959 _ZN2CA11Transaction4pushEv + 219
1 QuartzCore 0x00007fff8a106531 _ZN2CA11Transaction15ensure_implicitEv + 273
2 QuartzCore 0x00007fff8a10d66f _ZN2CA5Layer13thread_flags_EPNS_11TransactionE + 37
3 QuartzCore 0x00007fff8a10d5a7 _ZN2CA5Layer4markEPNS_11TransactionEjj + 79
4 QuartzCore 0x00007fff8a112cac _ZN2CA5Layer27contents_visibility_changedEPNS_11TransactionEb + 216
5 QuartzCore 0x00007fff8a112b65 _ZN2CA5Layer12mark_visibleEPNS_11TransactionEb + 261
6 QuartzCore 0x00007fff8a112b26 _ZN2CA5Layer12mark_visibleEPNS_11TransactionEb + 198
7 QuartzCore 0x00007fff8a112b26 _ZN2CA5Layer12mark_visibleEPNS_11TransactionEb + 198
8 QuartzCore 0x00007fff8a1128d1 _ZN2CA5Layer11set_visibleEj + 335
9 QuartzCore 0x00007fff8a1126b9 _ZN2CA7Context9set_layerEPKv + 75
10 MediaToolbox 0x00007fff857f155b FigCoreAnimationRendererInvalidate + 108
11 CoreFoundation 0x00007fff8ec763df CFRelease + 511
12 MediaToolbox 0x00007fff857d3a6b FigVideoCompositionProcessorInvalidate + 675
13 MediaToolbox 0x00007fff85791341 FigAssetWriterCreateWithURL + 18573
14 MediaToolbox 0x00007fff85791f7b FigAssetWriterCreateWithURL + 21703
15 CoreMediaAuthoringCrunchers 0x00000001046e2b99 AssetAudioSourcer_CreateInstance + 3865
I find that this goes away if I comment-out the following line - however the CATextLayer is not rendered:
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer inLayer:parentLayer];
Any thoughts anyone?
Adam
You must ensure any UI drawing occurs on the main thread. The line you commented out probably does some drawing internally, so you want to make sure this code is executed on the main thread. A couple ways to do this is by using the function dispatch_async() or the methods performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:modes:
- (void) someMethod
{
// You may need to load a container object to pass as myCustomData whose
// contents you then access in myCustomDrawing: if the data isn't accessible
// as instance data.
[...]
// Perform all drawing/UI updates on the main thread.
[self performSelectorOnMainThread:#selector(myCustomDrawing:)
withObject:myCustomData
waitUntilDone:YES];
[...]
}
- (void) myCustomDrawing:(id)myCustomData
{
// Perform any drawing/UI updates here.
videoComposition.animationTool = [AVVideoCompositionCoreAnimationTool videoCompositionCoreAnimationToolWithPostProcessingAsVideoLayer:videoLayer
inLayer:parentLayer];
}
For a related post on the difference between dispatch_async() and performSelectorOnMainThread:withObjects:waitUntilDone: see Whats the difference between performSelectorOnMainThread and dispatch_async on main queue?

Core Data throws NSInternalInconsistencyException "The context is still dirty after 100 attempts."

I struggle finding cause of the following exception. It occurs from time to time with no clear pattern I can repeat to reproduce problem.
Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Failed to process pending changes before save.
The context is still dirty after 100 attempts.
Typically this recursive dirtying is caused by a bad validation method,
-willSave, or notification handler.'
The application stores and process tracking data and deals with only one entity:
#interface CSTrackingEntry : NSManagedObject
#property (nonatomic, retain) NSString * data;
#property (nonatomic, retain) NSDate * dateRecorded;
#end
CSTracking entries are read, created and deleted in batches. Few up to dozen in a batch, once every couple of minutes. There is no notification handlers registered.
UPDATE: Stack captured
2012-02-03 10:26:11.121 BatteryNurse[17162:1803] An uncaught exception was raised
2012-02-03 10:26:11.121 BatteryNurse[17162:1803] Failed to process pending changes
before save. The context is still dirty after 100 attempts. Typically this recursive
dirtying is caused by a bad validation method, -willSave, or notification handler.
2012-02-03 10:26:11.264 BatteryNurse[17162:1803] *** Terminating app due to uncaught
exception 'NSInternalInconsistencyException', reason: 'Failed to process pending changes
before save. The context is still dirty after 100 attempts. Typically this recursive
dirtying is caused by a bad validation method, -willSave, or notification handler.'
*** Call stack at first throw:
(
0 CoreFoundation 0x00007fff8183f784 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00007fff89306f03 objc_exception_throw + 45
2 CoreData 0x00007fff8543a654 -[NSManagedObjectContext(_NSInternalChangeProcessing) _prepareForPushChanges:] + 244
3 CoreData 0x00007fff8543a0af -[NSManagedObjectContext save:] + 207
4 BatteryNurse 0x0000000100075ee6 __40-[CSTrackingEntry(Methods) deleteObject]_block_invoke_0 + 102
5 BatteryNurse 0x000000010007514f __42-[CSCoreDataKernel(CoreData) executeSync:]_block_invoke_0 + 79
6 libSystem.B.dylib 0x00007fff869bcfbb dispatch_barrier_sync_f + 79
7 BatteryNurse 0x00000001000750ee -[CSCoreDataKernel(CoreData) executeSync:] + 110
8 BatteryNurse 0x0000000100075e6f -[CSTrackingEntry(Methods) deleteObject] + 175
9 CoreFoundation 0x00007fff817ff123 -[NSArray makeObjectsPerformSelector:] + 499
10 BatteryNurse 0x000000010003a13f -[CSTracker(PrivateMethods) processAndSendBundlesToServer] + 383
11 BatteryNurse 0x00000001000393a4 __23-[CSTracker flushAsync]_block_invoke_0 + 420
12 libSystem.B.dylib 0x00007fff869c3d64 _dispatch_call_block_and_release + 15
13 libSystem.B.dylib 0x00007fff869a28d2 _dispatch_queue_drain + 251
14 libSystem.B.dylib 0x00007fff869a2734 _dispatch_queue_invoke + 57
15 libSystem.B.dylib 0x00007fff869a22de _dispatch_worker_thread2 + 252
16 libSystem.B.dylib 0x00007fff869a1c08 _pthread_wqthread + 353
17 libSystem.B.dylib 0x00007fff869a1aa5 start_wqthread + 13
You are modifying the object while it's being saved. If you're observing NSManagedObjectContextObjectsDidChange (which will be posted as part of the save, but before the actual saving happens), and you change objects are a result of that notification, you'll create a loop:
When you call -save: CoreData first calls -processPendingChanges: (if there are changes). As part of that CoreData sends out an NSManagedObjectContextObjectsDidChange notification. If additional objects changed while the notification was being processed, it calls -processPendingChanges: again, sends out the notification again, etc. Once there are no pending changes, CoreData persists the objects to the store. If pending changes keep appearing CoreData will eventually give up and print
The context is still dirty after 100 attempts.
That's the gist of it.

Resources