How to Avoid Realm-JS Crashes in React Native? - ios

I'm working on a React Native 0.40 app that uses Realm JS 1.0.0. I am experiencing crashes when reading/writing and some odd behaviors. For example, one of the crashes only happens when I add a second record to the table.
When it crashes, the output prints:
<Error>: MY_APP(18085,0x7000075ce000) malloc: *** mach_vm_map(size=18446744073345937408) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
(this is on the iOS simulator)
I've worked with Realm in Swift projects in the past where I had to be aware not to pass objects or collections around and also to not use the same realm from multiple threads, etc. However, I don't think those issues apply to RN. Right?
My general approach is to have a Realm factory like:
realm.js
export function getUserRealm(){
const realm = new Realm({
schema: combinedSchemas,
path: `main.realm`
});
console.log( "💿 User Realm Path:", realm.path );
return realm;
}
Then I call getUserRealm() from wherever it is that I'm using realm.
There are a few places where I do pass Results between functions and callbacks.
The main question is, what should I guard against in order to prevent crashes?

Related

iOS Core Data - Serious application error - attempt to insert nil - in less than 1%

iOS Core Data - Serious application error - attempt to insert nil
Hello,
My app runs actualy stable, but in seldom cases it crashes with this error message...
2019-04-02 20:48:52.437172+0200 myAppName[4422:1595677] [error] error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. -[__NSCFSet addObject:]: attempt to insert nil with userInfo (null)
2019-04-02 20:48:52.438246+0200 myAppName[4422:1595677] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
...when it tries to save the current context (this part in my code is still in objc):
- (void)saveChanges
{
dispatch_async(dispatch_get_main_queue(), ^{
NSError *err = nil;
BOOL succesful = [self->context save:&err];
if (!succesful)
{
NSLog(#"ERROR MESSAGE DURING SAVING CONTEXT: %#", [err localizedDescription]);
}
});
}
'seldom' means:
Most Customers do never experience the issue, for few customers it happens several times per day.
I was able to produce it 2 times during the last two days although I tried several ways to force this error (see below).
This is the setup:
The respective data is in one Entity (table)
A NSFetchedResultsController shows the data in an UITableView
User can hit a button to add a new record.
New record has only some basic data and initiates two API calls to two webservers
Each webserver response does update the record
After both are done (or were cancelled due to timeout), I call the saveChanges function from above only once.
All functions use the same context created by NSPersistentContainer as follow (this part is already in swift)
#objc lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "myAppName")
let description = NSPersistentStoreDescription(url: SomeHelper.urlForFileInDocFolder("storev7.data"))
container.persistentStoreDescriptions = [description]
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
If I could reproduce the error somehow, I could find an appropriate solution, but as it almost never happens, I'm stuck.
Do you have an idea how I could reproduce the error from above? Or do you have a clue what could cause the error in my case?
What I tried already to reproduce the error:
Create hundereds of record
Create hundereds of record in a few seconds
Create hundereds of record during switching internet connection on / off / on / off /...
Create hundereds of record during mixed from background and main thread (I removed the dispatch from saveChanges for that)
Create hundereds of record with different delays on the API (added random sleep function on the webserver)
Long time execution, the app run for 24 hours on a real device and created record each 2 minutes
Mixes of all of them
NSManagedObjects are restricted to a single queue. They are not thread-safe for reading or writing. Reading an NSManagedObject can cause a fault, which is a write operation. That means that NSManagedObjects retrieved from a main queue context (like viewContext) cannot be passed to other queues.
The details of all of this are discussed in the Core Data Programming Guide:
NSManagedObject instances are not intended to be passed between queues. Doing so can result in corruption of the data and termination of the application. When it is necessary to hand off a managed object reference from one queue to another, it must be done through NSManagedObjectID instances.
The general approach with NSPersistentContainer is to use something like viewContext exclusively on the main queue, and to use performBackgroundTask to handle background operations, or you can use newBackgroundContext to generate a background context, and use perform or performAndWait on it to manipulate objects that are fetched from that context.
Moving an object between contexts is done by fetching the same objectID in the other context (keeping in mind that this will return a fresh instance from the store).
You can track down mistakes by adding -com.apple.CoreData.ConcurrencyDebug 1 to your scheme. When you do this, errors will immediately trap on the delightfully named __Multithreading_Violation_AllThatIsLeftToUsIsHonor__.

NSUncaughtExceptionHandler when using Realm with Crashlytics

I've got Fabric installed in my app, with Crashlytics enabled via a simple Fabric.with([Crashlytics.self]) call in AppDelegate. Everything was working great, until I pulled in Realm. I have a dead-simple function;
class func listObjects() {
let realm = try? Realm()
if let realm = realm {
let objSet = realm.objects(TestObject.self)
print("Retrieved \(objSet.count) objects")
}
}
Calling the function actually works just fine, but I get an odd warning;
[Crashlytics:Crash] Warning: NSUncaughtExceptionHandler is '_ZZ34RLMInstallUncaughtExceptionHandlervEN3$_08__invokeEP11NSException' in '<...>/Frameworks/Realm.framework/Realm'
Has anyone come across this before?
I guess this is happening because Crashlytics checks whether the uncaught exception handler is overridden, because it is relying on that itself, but it is commonly misused for purposes where there would be less dangerous solutions. 🐉
Realm is using this for good reasons: we need to tear down open write transactions. While we are doing that, we still ensure to call the previously configured exception handler as you can see here. So Crashlytics won't loose it's ability to report any exceptions in your app.

Setting cachePolicy of a parse query crashes application

I'm developing in Swift using the latest version of Parse from the website. I am attempting to set my cache policy to the NetworkElseCache value, which is displayed below:
let userRelation = User.currentUser()?.relationForKey("friends")
let userQuery = userRelation!.query()
userQuery.cachePolicy = .NetworkElseCache
userQuery.findObjectsInBackgroundWithBlock {
(users, error) -> Void in
print("Success")
}
The error occurs on the line:
userQuery.cachePolicy = .NetworkElseCache
and if the line is removed, the application runs fine, the error produced is:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Method not allowed when Pinning is enabled.'
I really don't have any idea what to do from here, I only started iOS development about a week ago using Parse and Swift, so I'm a bit on the lost side. I don't understand the callstack either, or how it will help me find my problem.
Disable the LocalDataStore in your AppDelegate.m
So comment following line
Parse.enableLocalDatastore() // Comment this line and try
Here's the full explanation from the engineers at Parse. But yes, long story short, if you're using local datastore, you will not be able to also use different cache policies.

Unity iOS game crashing with NSInternalInconsistencyException

I am using Prime31's GameCenter Turn Based plugin in my game in order to handle online matches. A problem arises when I receive an "invitation to play" notification from Game Center while Game Center's matchmaker is showing (called using the plug-in => GameCenterTurnBasedBinding.findMatch(2,2,false); ).
The app crashes and the following output is shown in Xcode:
2012-08-20 08:39:27.050 Cabrais[1808:707] *** Assertion failure in -[NSIndexPath row], /SourceCache/UIKit/UIKit-1914.85/UITableViewSupport.m:2606
2012-08-20 08:39:27.052 Cabrais[1808:707] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid index path for use with UITableView. Index paths passed to table view must contain exactly two indices specifying the section and row. Please use the category on NSIndexPath in UITableView.h if possible.'
*** First throw call stack:
(0x355ec88f 0x33210259 0x355ec789 0x349e03a3 0x32d4d673 0x35dba49d 0x35dd90e5 0x35dd9379 0x32d4cefb 0x32d4bfd9 0x32d4b763 0x35da7657 0x32ceff37 0x3554b1fb 0x32716aa5 0x327166bd 0x327165c9 0x35dd8179 0x35da936b 0x35dbce65 0x35dbb6b3 0x33979c59 0x33984e91 0x355bf2ad 0x355424a5 0x3554236d 0x332dd439 0x32d1acd5 0x6954 0x3388)
terminate called throwing an exception(lldb)
I have tried disabling notifications through the Ipad/Iphone settings for both my app and GameCenter as well as through the code by removing all notification related code but this hasn't had any effect at all.
I know through debugging that the code in my function attached to GameCenterTurnBasedManager.handleTurnEventEvent doesn't get called before the crash occurs, and neither does the one registered to EtceteraManager.remoteNotificationReceived. (Both these function work perfectly fine otherwise.)
I have asked Prime31 and they have told me that the exception is a mishandling of the tables data source, and to file a bug report with Apple.
Has anyone experienced a similar crash/error while working with Unity?
And is there any way I can try to catch the notification before it arrives and remove the matchmaker or be able to handle the error from unity?
Any insight/help/comments would be greatly appreciated,
Thanks.

Error switching from vector<float> to vector<short>

I have an app I'm making where I would like to change a vector I'm creating from float to short. My code is in a header file like this:
vector<float> vertices;
and it works fine, but if I switch it to this:
vector<short> vertices;
and compile, it crashes with the following error:
malloc: *** error for object 0x1035804: incorrect checksum for freed object
- object was probably modified after being freed. *** set a breakpoint in
malloc_error_break to debug
I have no idea what's going on. If it helps, this is an OpenGL application I'm developing for the iPad.
I still don't know why my app wouldn't run when I changed my vector from float to short, but I solved the problem by creating a new vector object of shorts and using that instead. No more problems and works as expected.

Resources