Assertion failed: (result == KERN_SUCCESS), function +[XPCMachSendRight wrapSendRight:] - ios

In my IOS app, I'm sometimes getting the above error after a 3rd party library call, which seems to be allocating some memory, albeit not much (about 13MB);
Assertion failed: (result == KERN_SUCCESS), function +[XPCMachSendRight wrapSendRight:], file /SourceCache/XPCObjects/XPCObjects-46/XPCMachSendRight.m, line 27.
there's no indication where or why this is happening, and I couldn't find any help or even similar problems on the internet. Any ideas?

It happens when we call function before completion of another, i.e. it's threading problem. So check for that. For example:
[self dismissViewControllerAnimated:YES completion:^{
// correct place for code after completion
}];
// wrong place for code after completion

Related

WatchKit extension crash: "Program ended with exit code: 0"

For people wanting to reply quickly without reading the post: I am not hitting any memory limits. Read the whole post for details.
My WatchKit extension cannot properly function without the user first being "onboarded" through the phone app. Onboarding is where the user must accept the permissions that we require, so it's very crucial.
On my WatchKit extension, I wanted to display a simple warning for users who had not finished onboarding within our phone app yet.
As such, I thought I'd get the status of onboarding from the phone in two ways:
When the user opens the app/the app is activated (I use the willActivate method to detect this)
When the app finishes onboarding it sends a message to the watch of its completion (if the extension is reachable, of course)
Both of these combined would ensure that the status of onboarding is always kept in sync with the watch.
I wrote the first possibility in, utilizing reply handlers to exchange the information. It worked just fine, without any troubles. The warning telling the user to complete disappears, the extension does not crash, and all is well.
I then wrote in the second possibility, of the extension being reachable when the user finishes onboarding (with the phone then directly sending the companion the new status of onboarding). My extension crashes when it receives this message, and I am stuck with this odd error.
Program ended with exit code: 0
My extension does not even get a chance to handle the new onboarding status, the extension just quits and the above error is given to me.
I am not hitting any sort of memory limit. I have read the technical Q&A which describes what a memory usage limit error looks like, and I don't receive any sort of output like that whatsoever. As well, before the extension should receive the message, this is what my memory consumption looks like.
I have monitored the memory consumption of the extension right after finishing onboarding, and I see not a single spike indicating that I've gone over any kind of threshold.
I have tried going line by line over the code which manages the onboarding error, and I cannot find a single reason that it would crash with this error. Especially since the reply handler method of fetching the onboarding status works so reliably.
Here is the code of how I'm sending the message to the watch.
- (void)sendOnboardingStatusToWatch {
if(self.connected){
[self.session sendMessage:#{
LMAppleWatchCommunicationKey: LMAppleWatchCommunicationKeyOnboardingComplete,
LMAppleWatchCommunicationKeyOnboardingComplete: #(LMMusicPlayer.onboardingComplete)
}
replyHandler:nil
errorHandler:^(NSError * _Nonnull error) {
NSLog(#"Error sending onboarding status: %#", error);
}];
}
}
(All LMAppleWatchCommunicationKeys are simply #define'd keys with exactly their key as the string value. ie. #define LMAppleWatchCommunicationKey #"LMAppleWatchCommunicationKey")
Even though it's never called by the extension, here is the exact receiving code of the extension which handles the incoming data, if it helps.
- (void)session:(WCSession *)session didReceiveMessage:(NSDictionary<NSString *, id> *)message {
NSString *key = [message objectForKey:LMAppleWatchCommunicationKey];
if([key isEqualToString:LMAppleWatchCommunicationKeyOnboardingComplete]){
BOOL newOnboardingStatus = [message objectForKey:LMAppleWatchCommunicationKeyOnboardingComplete];
[[NSUserDefaults standardUserDefaults] setBool:newOnboardingStatus
forKey:LMAppleWatchCommunicationKeyOnboardingComplete];
dispatch_async(dispatch_get_main_queue(), ^{
for(id<LMWCompanionBridgeDelegate> delegate in self.delegates){
if([delegate respondsToSelector:#selector(onboardingCompleteStatusChanged:)]){
[delegate onboardingCompleteStatusChanged:newOnboardingStatus];
}
}
});
}
}
Before including this onboarding-related code, my WatchKit extension was tested by over 100 people, without any troubles. I am using the exact same custom error dialogue that I was using before, just with a different string. I cannot for the life of me figure out what is causing this crash, and the ambiguity of it has given me very little to work with.
Any help would be greatly appreciated. Thank you very much for taking your time to read my post.
Edit: I just tried creating a symbolic breakpoint for exit(), which is never hit. If I call exit() myself, it calls the breakpoint, so I know the breakpoint itself is working.

IBM Worklight 6.2 ChallengeHandler submitFailure: doesn't behave as expected

I am using Worklight 6.2 iOS native framework. I have implemented a custom MyChallengeHandler that subclasses ChallengeHandler, and logging in:
[[WLClient sharedInstance] login:#"SomeRealm" withDelegate:LoginListener];
In ChallengeHandler I can submit success, which calls onSuccess: in LoginListener:
[self submitSuccess:response];
However, I can't submit failure, which I was expecting to call onFailure: in LoginListener. In fact, it looks like there is no effect when calling submitFailure: and onFailure: never gets called in LoginListener.
Also, I don't see a declaration of submitFailure: in WL ChallengeHandler header, it is available only in BaseChallengeHandler.
My main point is, currently it looks like the LoginListener onFailure: method is never called, but there are cases when the handleChallenge: should fail. And LoginListener should get released.
Is this a known issue in Worklight, is there any workaround?
Update 1:
Just found a similar problem for JS client API, which isn't useful for native:
Adapter procedure call, reporting an authentication failure
Update 2:
This might be important. I am using Adapter authentication, but in the IBM example there is submitLoginForm:, maybe my issue is for Adapter authentication only.
[self submitAdapterAuthentication:invocationData options:nil]
It's a big vague so far but I will write some possibilities I think of. Let me know if any help, and I will update my answer.
1) Your code above says you use the class ChallangeHandler. I am not sure if the typo is only in StackOverflow or in your real code as well, but the class is ChallengeHandler, with a e.
Same for handleChallange instead of handleChallenge.
2) Did you register your challenge handler somewhere?
[[WLClient sharedInstance] registerChallengeHandler:[[MyChallengeHandler alloc] initWithViewController:self] ];
3) Do you ever get to the success of your LoginListener? And of your challenge handler?
You are correct that the documentation does not mentiond submitFailure - I will look into that.
However in code I wrote, I was able to use this without problems.
#implementation MyChallengeHandler
//...
-(void) onSuccess:(WLResponse *)response {
NSLog(#"inside challenge success");
[self.vc.navigationController popViewControllerAnimated:YES];
[self submitSuccess:response];
}
-(void) onFailure:(WLFailResponse *)response {
NSLog(#"inside challenge failure");
[self submitFailure:response];
}

Objective c Thread 1 signal SIGSTOP app crashes

I'm trying to track down an error that appears to be definitely a timing issue. I have an application that uses a Universal Framework. When the process is complete in the framework an NSNotification is sent back to the application. We have recently added a third party framework to our framework. Now, while the methods for the third party framework are being executed, as execution returns to our framework I receive the following error in the Console Output:
Assertion failed: (exclusive), function assert_locked, file ../dep/include/boost/boost_1_55_0/boost/thread/pthread/shared_mutex.hpp, line 51.
But I'm not sure that is the ultimate issue, because our framework continues to execute and the NSNotification is sent back to the application. Right after the Notification is sent and execution returns to the calling method (or the method call) in our framework I see a warning on the executing thread. Then, execution continues back to the original calling method and the warning goes away.
Here's the weird part. If I step through the code very slowly, it might just work. If I'm not slow enough I get the SIGSTOP and the code never returns to the UI. If I'm too fast, I get a SIGABRT.
I've been trying to find the exact issue using Instuments. This answer to a similar question backed up my suspicion that this is a timing issue. I think the boost assert_locked Assertion might have something to do with this.
My code is pretty boring but I know you want to see it, so here it is:
- (void)generateImageTemplates:(UIImage *)src
{
int result = 0;
cv::Mat image = *(cv::Mat*)[self cvMatFromUIImage:src];
user = IEngine_InitUser();
int userID=0;
result = IEngine_AddFingerprintRAW(user, UNKNOWN, image.data, image.size().width, image.size().height);
result = IEngine_RegisterUser(user, &userID);
[[NSNotificationCenter defaultCenter] postNotificationName:#"InnovatricsComplete" object:self];
}
If you're wondering what result is, it's an error code. So far these have all come back equal to 0. Meaning no errors. I'll work on handling these errors once I can get a successful return to the UI without crashing.
Control returns to the method call:
- (void)generateImageTemplates:(UIImage *)processedImage
{
[self.captureCommand generateImageTemplates:processedImage];
}
Control returns to the method call in the application View Controller:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == 0){
[self clearPressed:self.clearButton];
} else {
[self.cameraVC generateImageTemplates:self.processedImage];
}
}
Finally, the NSNotification callback code:
- (void)onInnovatricsComplete:(NSNotification *)note
{
[self.cameraVC willMoveToParentViewController:nil];
[self.cameraVC.view removeFromSuperview];
[self.cameraVC removeFromParentViewController];
}
I warned you it was pretty boring!
I'm completely stumped! Though I continue to surf the internet for clues, is there anybody out there who can help me resolve this issue?
Thank you.
Here are some screenshots (in reverse order):
look at NSUinteger’s answer in How to know where crash for postNotificationName:object:userInfo
the listener might be deallocated before it recieves the notification.

Getting "malloc: *** error: incorrect checksum for freed object" inconsistently

The full error is:
app(85540,0x38661a8) malloc: *** error for object 0x11214f84:
incorrect checksum for freed object - object was probably modified after being freed.
So I'm getting something that is quite hard to replicate and I suspect is has something to do with the way I have my block set up. What I'm trying to get is the current online status of gamers on Xbox Live, so I allocate 2 NSMutuableDictionaries in viewDidLoad. onlinePlayers is for holding the online status values of the gamers so it's not checked over and over again in cellForRowAtIndexPath when scrolling up and down. checkedPlayers is to prevent multiple calls going out trying to get the status of the same player. Anyway, if I keep launching the simulator over and over again, it will be fine 29/30 launches, but it always crashes at least once on launch with the above error when I'm trying to set the online status value for a gamer:
NSString* gamertag = cell.gamerTagLabel.text;
if (![_checkedPlayers containsObject:gamertag]) {
[_checkedPlayers addObject:gamertag];
[Utilities processJSONDataWithGamertag:gamertag andBlock:^(NSData *jsonData) {
id onlineStatus;
NSDictionary *allXboxAttributes = [Utilities returnJSONObject:jsonData];
// Get current Xbox Live Data
if ([allXboxAttributes objectForKey:#"data"]) {
NSDictionary *dataXboxAttributes = [allXboxAttributes objectForKey:#"data"];
onlineStatus = [dataXboxAttributes objectForKey:#"online"];
// Crashes on the line below
[_onlinePlayers setObject:onlineStatus forKey:gamertag];
// Return to main thread and update online status
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}];
}
If it helps for some reason, the value being returned from dataXboxAttributes is a BOOL. Any help would be much appreciated. Thanks!
You are getting the error in that method but the problem might be elsewhere.
To find the source of the problem, in XCode go to Product > Scheme > Edit Scheme, and under Diagnostics tab enable all the Malloc settings and Guard Malloc.
With that, run your application again, and XCode will stop at the line causing the problem.
from your code it looks like the completion block of processJSON isnt always on the main thread, synchronize access to onlinePlayers.
#synchronized will do I guess

NSOperation deadlocks and blocks NSOperationQueue

I use a subclass of NSOperation to upload large files to AWS S3 using Amazon's iOS SDK (v1.3.2). This all works fine, but some beta testers experience deadlocks (iOS 5.1.1). The result is that the NSOperationQueue in which the operations are scheduled is blocked as only one operation is allowed to run at one time. The problem is that I cannot reproduce the issue whereas the beta testers experience this problem every single time.
The operation is quite complex due to how the AWS iOS SDK works. However, the problem is not related to the AWS iOS SDK as far as I know based on my testing. The operation's main method is pasted below. The idea of the operation's main method is based on this Stack Overflow question.
- (void)main {
// Operation Should Terminate
_operationShouldTerminate = NO;
// Notify Delegate
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate operation:self isPreparingUploadWithUuid:self.uuid];
});
// Increment Network Activity Count
[self incrementNetworkActivityCount];
// Verify S3 Credentials
[self verifyS3Credentials];
while (!_operationShouldTerminate) {
if ([self isCancelled]) {
_operationShouldTerminate = YES;
} else {
// Create Run Loop
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
// Decrement Network Activity Count
[self decrementNetworkActivityCount];
NSLog(#"Operation Will Terminate");
}
The method that finalizes the multipart upload sets the boolean _operationShouldTerminate to YES to terminate the operation. That method looks like this.
- (void)finalizeMultipartUpload {
// Notify Delegate
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate operation:self didFinishUploadingUploadWithUuid:self.uuid];
});
// Operation Should Terminate
_operationShouldTerminate = YES;
NSLog(#"Finalize Multipart Upload");
}
The final log statement is printed to the console, but the while loop in the main method does not seem to exit as the final log statement in the operation's main method is not printed to the console. As a result, the operation queue in which the operation is scheduled, is blocked and any scheduled operations are not executed as a result.
The operation's isFinished method simply returns _operationShouldTerminate as seen below.
- (BOOL)isFinished {
return _operationShouldTerminate;
}
It is odd that the while loop is not exited and it is even more odd that it does not happen on any of my own test devices (iPhone 3GS, iPad 1, and iPad 3). Any help or pointers are much appreciated.
The solution to the problem is both complex and simple as it turns out. What I wrongly assumed was that the methods and delegate callbacks of the operation were executed on the same thread, that is, the thread on which the operation's main method was called. This is not always the case.
Even though this was true in my test and on my devices (iPhone 3GS), which is why I did not experience the problem myself. My beta testers, however, used devices with multicore processors (iPhone 4/4S), which caused some of the code to be executed on a thread different from the thread on which the operation's main method was invoked.
The result of this is that _operationShouldTerminate was modified in the finalizeMultipartUpload method on the wrong thread. This in turn means that the while loop of the main method was not exited properly resulting in the operation deadlocking.
In short, the solution is to update _operationShouldTerminate on the same thread as the main method was invoked on. This will properly exit the while loop and exit the operation.
There are a number of problems with your code, and I can offer two solutions:
1) read up on Concurrent NSOperations in Apple's Concurrency Programming Guide. To keep the runLoop "alive" you have to add either a port or schedule a timer. The main loop should contain a autorelease pool as you may not get one (see Memory Management in that same memo). You need to implement KVO to let the operationQueue know when your operation is finished.
2) Or, you can adopt a small amount of field tested hardened code and reuse it. That Xcode project contains three classes of interest to you: a ConcurrentOperation file that does well what you are trying to accomplish above. The Webfetcher.m class shows how to subclass the concurrent operation to perform an asynchronous URL fetch from the web. And the OperationsRunner is a small helper file you can add to any kind of class to manage the operations queue (run, cancel, query, etc). All of the above are less than 100 lines of code, and provide a base for you to get your code working. The OperationsRunner.h file provide a "how to do" too.

Resources