Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intermittent crash while running Realm in a background thread after upgrading to 5.0.3 #6577

Closed
nicolasgomollon opened this issue Jun 16, 2020 · 18 comments
Assignees

Comments

@nicolasgomollon
Copy link

nicolasgomollon commented Jun 16, 2020

Goals

Run Realm write code that runs in a background queue without crashing, as was possible in Realm 4.4.0. After upgrading to Realm 5.0.3, the sample code below crashes intermittently, but frequently enough to become a problem.

In our project, we have a Realm extension that implements several helper methods, one of which closely resembles the code sample found in this Realm documentation:
https://realm.io/docs/cookbook/swift/object-to-background/

I’m not sure if it’s related, but after coming across #6555, #6559, #6574, I have attempted implementing the fix from #6576, but the same crash still occurs.
EXC_BAD_ACCESS KERN_INVALID_ADDRESS

Expected Results

No crash, as in Realm 4.4.0.

Actual Results

Crashed: job_progress_queue
EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x00000003d7fd8a7c
0  Realm                          0x1064071f0 realm::Array::init_from_mem(realm::MemRef) + 12
1  Realm                          0x1064a8294 realm::Group::attach(unsigned long, bool, bool) + 196
2  Realm                          0x1064af054 realm::Group::advance_transact(unsigned long, unsigned long, realm::_impl::NoCopyInputStream&, bool) + 316
3  Realm                          0x10635a9dc void realm::Transaction::rollback_and_continue_as_read<realm::_impl::NullInstructionObserver>(realm::_impl::NullInstructionObserver*) + 588
4  Realm                          0x10635a030 realm::Transaction::rollback_and_continue_as_read() + 28
5  Realm                          0x106359e8c realm::_impl::transaction::cancel(realm::Transaction&, realm::BindingContext*) + 140
6  Realm                          0x1062b3c5c realm::Realm::cancel_transaction() + 264
7  Realm                          0x1061fedd0 -[RLMRealm cancelWriteTransaction] + 36
8  Realm                          0x1061ff3c0 -[RLMRealm dealloc] + 80
9  libobjc.A.dylib                0x1bc9d1358 AutoreleasePoolPage::releaseUntil(objc_object**) + 184
10 libobjc.A.dylib                0x1bc9d1244 objc_autoreleasePoolPop + 232
11 libswiftObjectiveC.dylib       0x1f37ccc2c autoreleasepool<A>(invoking:) + 76
12 MyJobApp                       0x101ad1b98 closure #1 in static Realm.runAsync(in:errorHandler:block:) + 15 (Realm+Helpers.swift:15)
13 MyJobApp                       0x100f97360 thunk for @escaping @callee_guaranteed () -> () + 56 (<compiler-generated>:56)
14 libdispatch.dylib              0x1bc93eec4 _dispatch_call_block_and_release + 32
15 libdispatch.dylib              0x1bc94033c _dispatch_client_callout + 20
16 libdispatch.dylib              0x1bc94685c _dispatch_lane_serial_drain + 568
17 libdispatch.dylib              0x1bc947290 _dispatch_lane_invoke + 400
18 libdispatch.dylib              0x1bc950928 _dispatch_workloop_worker_thread + 584
19 libsystem_pthread.dylib        0x1bc9a7714 _pthread_wqthread + 276
20 libsystem_pthread.dylib        0x1bc9ad9c8 start_wqthread + 8

Steps to Reproduce

See code sample below, but this is basically an intermittent but fairly frequent crash. In our code, we instantiate a Job object multiple times, as needed, to perform different tasks that we need completed.
For the purposes of the code sample below, assume code similar to the following is run multiple times:

let job: Job = Job()
job.start()

Code Sample

// Job.swift
public class Job: Object {
    
    @objc public dynamic var id: String = UUID().uuidString
    @objc public dynamic var progress: Double = 0.0
    
    public let tasks: List<Task> = .init()
    @objc public dynamic var runningTask: Task?
    
    public override static func primaryKey() -> String? {
        return "id"
    }
    
    private let jobProgressQueue: DispatchQueue = DispatchQueue(
        label: "job_progress_queue",
        qos: .utility,
        attributes: [],
        autoreleaseFrequency: .inherit,
        target: nil)
    
    public func start() {
        let primaryKey: String = self.id
        let jobProgressQueue: DispatchQueue = self.jobProgressQueue
        //
        // The specifics of `runningTask` are not important, other than the fact that
        // the `progressHandler` block is called frequently to update the caller on
        // its progress from another DispatchQueue.
        //
        runningTask.run(progressHandler: { (progress: Double) in
            Job.update(primaryKey, progress: progress, in: jobProgressQueue)
        })
    }
    
    public static func update(_ primaryKey: String, progress: Double, in dispatchQueue: DispatchQueue) {
        Realm.runAsync(in: dispatchQueue) { (realm: Realm) in
            guard let job: Job = realm.object(ofType: Job.self, forPrimaryKey: primaryKey) else { return }
            try? realm.write {
                guard !job.isInvalidated else { return }
                job.progress = progress
            }
        }
    }
    
}
// Realm+Helpers.swift
extension Realm {
    
    public static func runAsync(in dispatchQueue: DispatchQueue, errorHandler: @escaping (_ error: Swift.Error) -> Void = { _ in return }, block: @escaping (Realm) -> Void) {
        dispatchQueue.async {
            autoreleasepool { // <--- Thread 49: EXC_BAD_ACCESS (code=1, address=0x3d7fd8a7c)
                do {
                    let realm: Realm = try Realm()
                    block(realm)
                } catch {
                    errorHandler(error)
                }
            }
        }
    }
    
}

Version of Realm and Tooling

Realm framework version: 5.0.3

Realm Object Server version: N/A

Xcode version: 11.5 (11E608c)

iOS version: 13.5 (17F75)

Dependency manager + version: CocoaPods 1.9.3

@oscarkockum
Copy link

oscarkockum commented Jun 16, 2020

Yes, I have the same issue, tried #6576 but with the same crash.

Need to be able to fix as soon as possible due to its not possible to revert to 4.x?

@nalexn
Copy link

nalexn commented Jul 1, 2020

+++

Any update on this one?

@WWDGitHup
Copy link

Have you solved the problem yet?

@nicolasgomollon
Copy link
Author

No updates on my end @occe @nalexn @WWDGitHup, we’re still waiting for someone from the Realm team to take a look and see what could be going wrong. We were lucky enough to catch this one early in our testing in one of our internal builds, so we were able to revert back to 4.4.0 before shipping to the public.

@tgoyne
Copy link
Member

tgoyne commented Jul 2, 2020

There isn't really any starting point for looking into this. All that I can say from the stack trace is that it's somehow getting to the end of the autoreleasepool while still in a write transaction, and then something's going wrong when rolling back the write transaction. The only way for this to happen with the given code should be if something inside the write transaction threw an exception (note: not a swift error). The simplicity of the write being performed doesn't leave a lot of possibilities for what could be going wrong; a memory allocation failure that we don't handle gracefully is the only thing that comes to mind.

@markltownsend
Copy link

markltownsend commented Jul 28, 2020

I am having a similar crash when running the app in the background. I just upgraded to the latest v5.3.2.

It will work for a few seconds and then a crash in Realm. The code is doing a fairly simple realm.add. I tried it wrapped in an autoreleasepool and not. Not difference. It is doing the writes in a fairly quick manner if that matters.

Also, if it matters, I have a writeRealm that I always use a background thread with and a readRealm that I use the main thread. I figured this would make things more thread safe without having to go through the ThreadSafeRef dance.

@leemaguire
Copy link
Contributor

For anyone experiencing this issue, could you create a sample app that reproduces this and send it to us? Thanks!

@marinofaggiana
Copy link

marinofaggiana commented Aug 11, 2020

Please, several user with:

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000000001ea
VM Region Info: 0x1ea is not in any region.  Bytes before following region: 4336107030
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      UNUSED SPACE AT START
--->  
      __TEXT                 000000010273c000-00000001027a0000 [  400K] r-x/r-x SM=COW  ...app/abc

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [15801]
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   Realm                         	0x000000010363d8f4 realm::util::EncryptedFileMapping::read_barrier(void const*, unsigned long, unsigned long (*)(char const*)) + 32
1   Realm                         	0x000000010332e53c realm::util::do_encryption_read_barrier(void const*, unsigned long, unsigned long (*)(char const*), realm::util::EncryptedFileMapping*) + 84
2   Realm                         	0x000000010332e53c realm::util::do_encryption_read_barrier(void const*, unsigned long, unsigned long (*)(char const*), realm::util::EncryptedFileMapping*) + 84
3   Realm                         	0x00000001035dd2ac realm::StringData realm::ConstObj::_get<realm::StringData>(realm::ColKey::Idx) const + 408
4   Realm                         	0x0000000103375258 invocation function for block in objc_object* (anonymous namespace)::makeBoxedGetter<realm::StringData>(unsigned long) + 144 (RLMAccessor.mm:71)

Date/Time:           2020-08-10 22:57:45.4651 +0200
Launch Time:         2020-08-10 20:55:41.8655 +0200
OS Version:          iPhone OS 13.6 (17G68)
Release Type:        User
Baseband Version:    2.07.00
Report Version:      104

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000002d3b662cc
VM Region Info: 0x2d3b662cc is not in any region.  Bytes after previous region: 90829  Bytes before following region: 25124148
      REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
      mapped file            00000002d1610000-00000002d3b50000 [ 37.2M] r--/rw- SM=S/A  ...t_id=8f017d59
--->  GAP OF 0x180c000 BYTES
      Image IO               00000002d535c000-00000002d62e0000 [ 15.5M] rw-/rwx SM=PRV  

Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [17735]
Triggered by Thread:  0

Thread 0 name:
Thread 0 Crashed:
0   Realm                         	0x0000000103ce9750 realm::Array::init_from_mem(realm::MemRef) + 12
1   Realm                         	0x0000000103d7f1b4 realm::Group::attach(unsigned long, bool, bool) + 196
2   Realm                         	0x0000000103d8690c realm::Group::advance_transact(unsigned long, unsigned long, realm::_impl::NoCopyInputStream&, bool) + 380
3   Realm                         	0x0000000103c60038 void realm::Transaction::rollback_and_continue_as_read<realm::_impl::NullInstructionObserver>(realm::_impl::NullInstructionObserver*) + 408 (db.hpp:928)
4   Realm                         	0x0000000103c5edb8 realm::_impl::transaction::cancel(realm::Transaction&, realm::BindingContext*) + 704 (db.hpp:576)
5   Realm                         	0x0000000103c3e5e0 realm::Realm::cancel_transaction() + 64 (shared_realm.cpp:686)
6   Realm                         	0x0000000103c0dd14 -[RLMRealm cancelWriteTransaction] + 20 (RLMRealm.mm:730)
7   Realm                         	0x0000000103c0df94 -[RLMRealm dealloc] + 52 (RLMRealm.mm:808)
8   libobjc.A.dylib               	0x0000000193b83380 AutoreleasePoolPage::releaseUntil(objc_object**) + 184 (NSObject.mm:780)
9   libobjc.A.dylib               	0x0000000193b8326c objc_autoreleasePoolPop + 232 (NSObject.mm:1040)
10  CoreFoundation                	0x0000000193e5e320 _CFAutoreleasePoolPop + 32 (NSObject.m:790)
11  CoreFoundation                	0x0000000193dc7594 __CFRunLoopRun + 1700 (CFRunLoop.c:3072)
12  CoreFoundation                	0x0000000193dc6bc8 CFRunLoopRunSpecific + 480 (CFRunLoop.c:3192)
13  GraphicsServices              	0x000000019e1a85cc GSEventRunModal + 164 (GSEvent.c:2246)
14  UIKitCore                     	0x0000000197f79744 UIApplicationMain + 1936 (UIApplication.m:4823)

@leemaguire
Copy link
Contributor

@marinofaggiana This looks like a separate issue, please open a new issue and fill out the template accordingly. Thanks!

@leemaguire
Copy link
Contributor

Can everyone please update to the latest version of Realm (5.3.4) Thanks

@duncangroenewald
Copy link

Actually you might want to try upgrading to Realm (5.3.5) since that fixes a common thread related crash.

@leemaguire
Copy link
Contributor

Closing this issue as v5.3.5 contains a relevant fix related to this issue.

@goa
Copy link

goa commented Sep 2, 2020

I am still seeing this exact same crash in v5.3.5.

@geragray
Copy link
Contributor

geragray commented Sep 3, 2020

@goa sorry to hear this and thank you for getting back to us. Realm Core team is prioritizing working on v5.x crashes right now.

@leemaguire
Copy link
Contributor

@goa Could you open a new issue and fill out the issue template so that we may help you in the best way possible? Thanks.

@finnschiermer
Copy link

Likely the same issue as #6408

@geragray
Copy link
Contributor

@goa Could you please upgrade and try reproducing with realm-cocoa 5.4.0 (which included a fix for this problem realm/realm-core#3904)

@pavel-ship-it
Copy link
Contributor

This issue has been automatically closed because there has been no response to our request for more information from the original author. With only the information that is currently in the issue, we don't have enough information to take action. Please reach out if you have or find the answers we need so that we can investigate further.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 18, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests