where to look for a bug. document, app delegate or both? - objective-c

following situation: i have a document based App. by default when i open the app it displays just the menu on top of the screen. then i hit file->new and it opens up a brand new document.xib interface. working fine on my main pc. but on my secodnary pc running 10.6.8 the app crashes as soon as i run it. (code is compiled with the proper target...)
this application is crashing BEFORE i even see the main menu at the top. could the cause of the crash still be inside the document's xib file? or will it most likely be in the code that is outside the document part? what i mean is: is the code checked completely at the application lounch or does it onyl cause a crash when it reaches the code that is causing it?
thanks
edit
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 ??? 000000000000000000 0 + 0
1 com.apple.AppKit 0x0000000100def22e -[NSCustomObject nibInstantiate] + 416
2 com.apple.AppKit 0x0000000100def01b -[NSIBObjectData instantiateObject:] + 259
3 com.apple.AppKit 0x0000000100dee406 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 336
4 com.apple.AppKit 0x0000000100deca91 loadNib + 226
5 com.apple.AppKit 0x0000000100debfa1 +[NSBundle(NSNibLoading)_loadNibFile:nameTable:withZone:ownerBundle:] + 248
6 com.apple.AppKit 0x0000000100debdd9 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 326
7 com.apple.AppKit 0x0000000100de935b NSApplicationMain + 279
8 mad-sharky.com.Stockuploader 0x0000000100001194 0x100000000 + 4500

The problem lies not in the XIB file, but rather in one of the objects in said file that is being instantiated incorrectly. Something about the object is causing it's -initWithCoder: method to fail. It appears you're probably not calling through to super in said method, and are simply returning self, which is not allowed.
The other possibility is that you have a "ghost outlet". Sometimes, when an IBOutlet is created and linked, then the piece of code that declares it is removed, IB doesn't de-link the outlet, and NSCoder tries to dearchive a nil outlet.

found the problem. here it is:
now it works without any problems!

Related

How to easily investigate 'This application is modifying the autolayout engine from a background thread' [duplicate]

Been encountering this error a lot in my OS X using swift:
"This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes. This will cause an exception in a future release."
I have a my NSWindow and I'm swapping in views to the contentView of the window. I get the error when I try and do a NSApp.beginSheet on the window, or when I add a subview to the window. Tried disabling autoresize stuff, and I don't have anything using auto layout. Any thoughts?
Sometimes it's fine and nothing happens, other times it totally breaks my UI and nothing loads
It needs to be placed inside a different thread that allows the UI to update as soon as execution of thread function completes:
Modern Swift:
DispatchQueue.main.async {
// Update UI
}
Older versions of Swift, pre Swift 3.
dispatch_async(dispatch_get_main_queue(){
// code here
})
Objective-C:
dispatch_async(dispatch_get_main_queue(), ^{
// code here
});
You get similar error message while debugging with print statements without using 'dispatch_async'
So when you get that error message, its time to use
Swift 4
DispatchQueue.main.async { //code }
Swift 3
DispatchQueue.main.async(){ //code }
Earlier Swift versions
dispatch_async(dispatch_get_main_queue()){ //code }
The "this application is modifying the autolayout engine from a background thread" error is logged in the console long after the actual problem occured, so debugging this can be hard without using a breakpoint.
I used #markussvensson's answer to detect my problem and found it using this Symbolic Breakpoint (Debug > Breakpoints > Create Symbolic Breakpoint):
Symbols: [UIView layoutIfNeeded] or [UIView updateConstraintsIfNeeded]
Condition: !(BOOL)[NSThread isMainThread]
Build and run the app on the emulator and replicate the steps that lead to the error message being thrown (the app will be slower than usual!). Xcode will then stop the app and mark the line of code (e.g. the call of a func) that's accessing the UI from a background thread.
When you try to update a text field value or adding a subview inside a background thread, you can get this problem. For that reason, you should put this kind of code in the main thread.
You need to wrap methods that call UI updates with dispatch_asynch to get the main queue. For example:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.friendLabel.text = "You are following \(friendCount) accounts"
})
EDITED - SWIFT 3:
Now, we can do that following the next code:
// Move to a background thread to do some long running work
DispatchQueue.global(qos: .userInitiated).async {
// Do long running task here
// Bounce back to the main thread to update the UI
DispatchQueue.main.async {
self.friendLabel.text = "You are following \(friendCount) accounts"
}
}
For me, this error message originated from a banner from Admob SDK.
I was able to track the origin to "WebThread" by setting a conditional breakpoint.
Then I was able to get rid of the issue by encapsulating the Banner creation with:
dispatch_async(dispatch_get_main_queue(), ^{
_bannerForTableFooter = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
...
}
I don't know why this helped as I cannot see how this code was called from a non-main-thread.
Hope it can help anyone.
I had this problem since updating to the iOS 9 SDK when I was calling a block that did UI updates within an NSURLConnection async request completion handler. Putting the block call in a dispatch_async using dispatch_main_queue solved the issue.
It worked fine in iOS 8.
Had the same problem because I was using performSelectorInBackground.
Main problem with "This application is modifying the autolayout engine from a background thread" is that it seem to be logged a long time after the actual problem occurs, this can make it very hard to troubleshoot.
I managed to solve the issue by creating three symbolic breakpoints.
Debug > Breakpoints > Create Symbolic Breakpoint...
Breakpoint 1:
Symbol: -[UIView setNeedsLayout]
Condition: !(BOOL)[NSThread isMainThread]
Breakpoint 2:
Symbol: -[UIView layoutIfNeeded]
Condition: !(BOOL)[NSThread isMainThread]
Breakpoint 3:
Symbol: -[UIView updateConstraintsIfNeeded]
Condition: !(BOOL)[NSThread isMainThread]
With these breakpoints, you can easily get a break on the actual line where you incorrectly call UI methods on non-main thread.
You must not change the UI offside the main thread! UIKit is not thread safe, so that above problem and also some other weird problems will arise if you do that. The app can even crash.
So, to do the UIKit operations, you need to define block and let it be executed on the main queue: such as,
NSOperationQueue.mainQueue().addOperationWithBlock {
}
Obviously you are doing some UI update on back ground thread. Cant predict exactly where, without seeing your code.
These are some situations it might happen:-
you might be doing something on background thread and not using. Being in the same function this code is easier to spot.
DispatchQueue.main.async { // do UI update here }
calling a func doing web request call on background thread and its completion handler calling other func doing ui update.
to solve this try checking code where you have updated the UI after webrequest call.
// Do something on background thread
DispatchQueue.global(qos: .userInitiated).async {
// update UI on main thread
DispatchQueue.main.async {
// Updating whole table view
self.myTableview.reloadData()
}
}
I had this issue while reloading data in UITableView. Simply dispatching reload as follows fixed the issue for me.
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
I had the same problem. Turns out I was using UIAlerts that needed the main queue. But, they've been deprecated.
When I changed the UIAlerts to the UIAlertController, I no longer had the problem and did not have to use any dispatch_async code. The lesson - pay attention to warnings. They help even when you don't expect it.
You already have the correct code answer from #Mark but, just to share my findings:
The issue is that you are requesting a change in the view and assuming that it will happen instantly. In reality, the loading of a view depends on the available resources. If everything loads quickly enough and there are no delays then you don't notice anything. In scenarios, where there is any delay due to the process thread being busy etc, the application runs into a situation where it is supposed to display something even though its not ready yet. Hence, it is advisable to dispatch these requests in a asynchronous queues so, they get executed based on the load.
I had this issue when I was using TouchID if that helps anyone else, wrap your success logic which likely does something with the UI in the main queue.
It could be something as simple as setting a text field / label value or adding a subview inside a background thread, which may cause a field's layout to change. Make sure anything you do with the interface only happens in the main thread.
Check this link: https://forums.developer.apple.com/thread/7399
I had the same issue when trying to update error message in UILabel in the same ViewController (it takes a little while to update data when trying to do that with normal coding). I used DispatchQueue in Swift 3 Xcode 8 and it works.
If you want to hunt this error, use the main thread checker pause on issues checkbox.
Fixing it is easy most of the times, dispatching the problematic line in the main queue.
For me the issue was the following.
Make sure performSegueWithIdentifier: is performed on the main thread:
dispatch_async (dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:#"ViewController" sender:nil];
});
Swift 4,
Suppose, if you are calling some method using operation queue
operationQueue.addOperation({
self.searchFavourites()
})
And suppose function searchFavourites is like,
func searchFavourites() {
DispatchQueue.main.async {
//Your code
}
}
if you call, all code inside the method "searchFavourites" on the main thread, it will still give an error if you are updating some UI in it.
This application is modifying the autolayout engine from a background
thread after the engine was accessed from the main thread.
So use solution,
operationQueue.addOperation({
DispatchQueue.main.async {
self.searchFavourites()
}
})
For this kind of scenario.
Here check out this line from the logs
$S12AppName18ViewControllerC11Func()ySS_S2StF + 4420
you can check that which function calling from the either background thread or where you are calling api method you need to call your function from the main thread like this.
DispatchQueue.main.async { func()}
func() is that function you want to call in the result of api call
success or else.
Logs Here
This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
Stack:(
0 Foundation 0x00000001c570ce50 <redacted> + 96
1 Foundation 0x00000001c5501868 <redacted> + 32
2 Foundation 0x00000001c5544370 <redacted> + 540
3 Foundation 0x00000001c5543840 <redacted> + 396
4 Foundation 0x00000001c554358c <redacted> + 272
5 Foundation 0x00000001c5542e10 <redacted> + 264
6 UIKitCore 0x00000001f20d62e4 <redacted> + 488
7 UIKitCore 0x00000001f20d67b0 <redacted> + 36
8 UIKitCore 0x00000001f20d6eb0 <redacted> + 84
9 Foundation 0x00000001c571d124 <redacted> + 76
10 Foundation 0x00000001c54ff30c <redacted> + 108
11 Foundation 0x00000001c54fe304 <redacted> + 328
12 UIKitCore 0x00000001f151dc0c <redacted> + 156
13 UIKitCore 0x00000001f151e0c0 <redacted> + 152
14 UIKitCore 0x00000001f1514834 <redacted> + 868
15 UIKitCore 0x00000001f1518760 <redacted> + 104
16 UIKitCore 0x00000001f1543370 <redacted> + 1772
17 UIKitCore 0x00000001f1546598 <redacted> + 120
18 UIKitCore 0x00000001f14fc850 <redacted> + 1452
19 UIKitCore 0x00000001f168f318 <redacted> + 196
20 UIKitCore 0x00000001f168d330 <redacted> + 144
21 AppName 0x0000000100b8ed00 $S12AppName18ViewControllerC11Func()ySS_S2StF + 4420
22 AppName 0x0000000100b8d9f4 $S12CcfU0_y10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 2384
23 App NAme 0x0000000100a98f3c $S10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 316
24 CFNetwork 0x00000001c513aa00 <redacted> + 32
25 CFNetwork 0x00000001c514f1a0 <redacted> + 176
26 Foundation 0x00000001c55ed8bc <redacted> + 16
27 Foundation 0x00000001c54f5ab8 <redacted> + 72
28 Foundation 0x00000001c54f4f8c <redacted> + 740
29 Foundation 0x00000001c55ef790 <redacted> + 272
30 libdispatch.dylib 0x000000010286f824 _dispatch_call_block_and_release + 24
31 libdispatch.dylib 0x0000000102870dc8 _dispatch_client_callout + 16
32 libdispatch.dylib 0x00000001028741c4 _dispatch_continuation_pop + 528
33 libdispatch.dylib 0x0000000102873604 _dispatch_async_redirect_invoke + 632
34 libdispatch.dylib 0x00000001028821dc _dispatch_root_queue_drain + 376
35 libdispatch.dylib 0x0000000102882bc8 _dispatch_worker_thread2 + 156
36 libsystem_pthread.dylib 0x00000001c477917c _pthread_wqthread + 472
37 libsystem_pthread.dylib 0x00000001c477bcec start_wqthread + 4
)
I also encountered this problem, seeing a ton of these messages and stack traces being printed in the output, when I resized the window to a smaller size than its initial value. Spending a long time figuring out the problem, I thought I'd share the rather simple solution. I had once enabled Can Draw Concurrently on an NSTextView through IB. That tells AppKit that it can call the view's draw(_:) method from another thread. After disabling it, I no longer got any error messages. I didn't experience any problems before updating to macOS 10.14 Beta, but at the same time, I also started modifying the code to perform work with the text view.

Tracking down a SIGSEGV…

So I've got this weird SIGSEGV happening at very few (less than 1%) of my users…
From the stack trace it looks like an over-release
Thread 0 Crashed:
0 libobjc.A.dylib 0x00007fff9a3f916f objc_release + 31
1 libobjc.A.dylib 0x00007fff9a3f7ac4 (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 475
2 CoreFoundation 0x00007fff9cc5c102 _CFAutoreleasePoolPop + 49
3 Foundation 0x00007fff96992cb6 -[NSAutoreleasePool drain] + 152
4 AppKit 0x00007fff9138409b -[NSApplication run] + 892
5 AppKit 0x00007fff91306520 NSApplicationMain + 1175
6 RailModeller Pro 0x000000010b60578b main (main.m:30)
7 libdyld.dylib 0x00007fff9a36b5ad start + 0
..but no matter what I try,
even with the very same data,
following the exact same steps as the users,
same OS/patch level,
using Address Sanitizer (Xcode 7.3),
using Zombies instrument,
using Guard Malloc
all appears to be fine.
The function crashing is a pretty common one in the app and I'd be drowning in bug reports (both from the automated bug reporting system as well as users getting in touch) if this were a more common issue.
However, to these (<1%) users the app appears effectively unusable.
Any hints on how to track down this issue much appreciated!

How to print a usable stack trace in Cocoa app?

I'm using [NSThread callStackSymbols] to log a stack trace when my app encounters an NSError, to help me troubleshoot and debug behavior my users see. It produces output like this:
(
0 MyApp 0x00000001067b02fc MyApp + 451324
1 AppKit 0x00007fff89e922c2 -[NSApplication finishLaunching] + 354
2 AppKit 0x00007fff89e91e05 -[NSApplication run] + 231
3 AppKit 0x00007fff89e14520 NSApplicationMain + 1176
4 libdyld.dylib 0x00007fff9bae25ad start + 1
)
How do I print in that same log statement the address into which MyApp has been loaded, so I can manually symbolicate the stack frame (in this case, finding out what method resides at 451324)?
When looking at a crash report, for example, there is a section labeled "Binary Images" that lists the address of each binary. I'm looking for a way to get that for my own process, at runtime.
I found this Apple documentation page, which shows how to symbolicate by shelling out to atos, but I'd prefer a Cocoa API call.

Can't figure out "Unrecognized selector sent to instance" source

So I am at my wit's end on this, I am toggling some sharedprefs back and forth, and eventually it makes my app crash. I thought it was because I wasn't deallocating observers properly, but upon looking at the crash log it says that an unrecognized selector is sent to instance. Does anybody know more about crash logs that can tell me more about what's happening? I can get the basic gist of what's happening out of the log, but I'm still a rookie and a lot of the information is going over my head.
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType _adjustLengthDueToViewFrameChange:]: unrecognized selector sent to instance 0x608000095b80'
terminating with uncaught exception of type NSException
abort() called
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff8fdcb25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff92afae75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8fdce12d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x00007fff8fd29272 ___forwarding___ + 1010
4 CoreFoundation 0x00007fff8fd28df8 _CF_forwarding_prep_0 + 120
5 CoreFoundation 0x00007fff8fd99e0c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
6 CoreFoundation 0x00007fff8fc8d82d _CFXNotificationPost + 2893
7 AppKit 0x00007fff915a4003 -[NSView _postFrameChangeNotification] + 434
8 AppKit 0x00007fff915ad6c2 -[NSView setFrameSize:] + 1586
9 AppKit 0x00007fff915ad049 -[NSView setFrame:] + 294
10 AppKit 0x00007fff915acc2b -[NSWindow setContentView:] + 453
11 AppKit 0x00007fff91beeace -[NSStatusItem setView:] + 224
12 MyAppHelper 0x00000001000775f5 -[NSStatusItem(BCStatusItem) setupView] + 85
13 MyAppHelper 0x000000010000cdbb -[MyAppHelperCapHelperServer createStatusBarItem] + 299
14 MyAppHelper 0x000000010000cf5b -[MyAppHelperCapHelperServer insertCaptureMenu] + 43
15 MyAppHelper 0x000000010000fe3d -[MyAppHelperHelperServer observeValueForKeyPath:ofObject:change:context:] + 733
16 Foundation 0x00007fff927e8f28 NSKeyValueNotifyObserver + 387
17 Foundation 0x00007fff927e80f8 NSKeyValueDidChange + 453
18 Foundation 0x00007fff927ecbe6 -[NSObject(NSKeyValueObserverNotification) didChangeValueForKey:] + 118
19 MyAppHelperHelper 0x0000000100109a3d __57-[RMSharedUserDefaults __applyBaselineAndNotify:updates:]_block_invoke + 349
20 CoreFoundation 0x00007fff8fd086df __65-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 111
21 CoreFoundation 0x00007fff8fd085ee -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 222
Primarily, I have no idea what it means in the exception information: [__NSCFType _adjustLengthDueToViewFrameChange:]. I cannot seem to find any information anywhere.
Thanks in advance!
First, I assume you are manually managing the memory, if so, I'll Highly recommend you to migrate to ARC (Automatic Reference Counting) it will manage the memory for you and you wont have this type or errors anymore. There are plenty of tutorials on Google of how to do this.
You can read more here: Transitioning to ARC Release Notes
Second, without ARC, this kind of error is often caused because you are calling a method/selector on an already released object, that's why the method/selector is not recognized.
This assuming you take care of clearing all the warnings on your project, if not, first go and check if there isn't a warning already pointing that you are trying to call a method/selector that doesn't exist for some object in your app. You can use the Analyze option as mentioned on the comments of this answer. To do that just Cmd+Shift+b, select the Analyze option from the Product Menu or Press and Hold the "Play" button you use to build the app and you will see the Analyze option as well.
Finally, I see you are using User Defaults. I'll recommend making sure you are retaining the values you are receiving from the User Defaults as they came with autorelease. This will explain why the compiler is not able to show the exact line of code where this error is happening, because it happens until the objet is autoreleased.
If is not the User Defaults I'll go and check all my autoreleased variables, is most likely that the problem is with one of them.

NSEvent charactersIgnoringModifiers randomly throws "TSMProcessRawKeyCode failed" exception

Our Mac cocos2d app (http://deepworldgame.com) has been randomly throwing "TSMProcessRawKeyCode failed" exceptions for some time now, and I'm wondering if anyone has experienced this error or knows how to prevent it.
It always happens via the [NSEvent charactersIgnoringModifiers] call within ccKeysDown or ccKeysUp (it also happens for [NSEvent characters] without the modifiers). I don't think it's related to specific keys. Sometimes it only happens one time and the app continues to function afterward (if the exception is caught), but other times it essentially locks up keyboard input indefinitely and continues to cause exceptions with all future keypresses (again, when these exceptions are caught).
I've found little on the internets regarding this issue, unfortunately. One place I did find was in the Adium source code (https://bitbucket.org/adium/adium/src/6d1f9b903525/Source/AIExceptionController.m), which catches this exception with the comments:
//Ignore various known harmless or unavoidable exceptions (From the system or system hacks)
...
// [TSMProcessRawKeyCode] May be raised by -[NSEvent charactersIgnoringModifiers]
It is indeed harmless when thrown once, but when the occasion happens that it continuously fires, it's a real problem - especially when you're in fullscreen mode and can't use cmd-F to escape!
So, if anyone has any thoughts or experience, I would be HIGHLY grateful. This is pretty much the one remaining superbug in our application, and I would love to squash it into dust.
Thanks!
Here is the typical stack trace (MacManager.m is our object which implements the cocos2d keyboard delegate protocol):
Crashed Thread: 7 CVDisplayLink
Exception Type: EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000002, 0x0000000000000000
Application Specific Information:
objc[28871]: garbage collection is OFF
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'TSMProcessRawKeyCode failed (-192)'
*** Call stack at first throw:
(
0 CoreFoundation 0x95b27d87 __raiseError + 231
1 libobjc.A.dylib 0x9315a149 objc_exception_throw + 155
2 CoreFoundation 0x95a8f619 +[NSException raise:format:arguments:] + 137
3 CoreFoundation 0x95a8f589 +[NSException raise:format:] + 57
4 AppKit 0x9ac01c1f _convertEventRefToString + 300
5 AppKit 0x9ab23b5e -[NSEvent charactersIgnoringModifiers] + 880
6 Deepworld 0x0001fd8a -[MacManager ccKeyDown:] + 65
7 CoreFoundation 0x95a7d091 -[NSObject performSelector:withObject:] + 65
8 Deepworld 0x0006bc95 -[CCEventDispatcher keyDown:] + 80
9 CoreFoundation 0x95a7d091 -[NSObject performSelector:withObject:] + 65
10 Deepworld 0x0006c014 -[CCEventDispatcher dispatchQueuedEvents] + 143
11 Deepworld 0x0006a9a4 -[CCDirectorDisplayLink getFrameForTime:] + 155
12 Deepworld 0x0006aaf1 MyDisplayLinkCallback + 40
13 CoreVideo 0x9b44a5e1 _ZN13CVDisplayLink9performIOEP11CVTimeStamp + 489
14 CoreVideo 0x9b4494e4 _ZN13CVDisplayLink11runIOThreadEv + 876
15 CoreVideo 0x9b449161 _ZL13startIOThreadPv + 160
16 libsystem_c.dylib 0x968a4ed9 _pthread_start + 335
17 libsystem_c.dylib 0x968a86de thread_start + 34
)
I don't think sending events in general is thread-safe, not to mention from a thread that has been created not within +[NSThread detachNewThreadSelector:toTarget:withObject:] (a thread created using the Objective-C run-time has __NSThread__main__ in the backtrace).
I guess your app is the Deepworld binary part - when dispatching events, try using -[NSObject performSelectorOnMainThread:waitUntilDone:] instead, dispatching the events on the main thread.