rollbar / rollbar-ios

Objective-C library for crash reporting and logging with Rollbar.

Home Page:https://docs.rollbar.com/docs/ios

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RollbarFileReader crash in background

okalentiev opened this issue Β· comments

I think we finally resolved the crashes related to the data we are sending to Rollbar. However, there's another one 😞

We use NSFileProtectionComplete data protection so accessing app data in the background is not possible unless the file is explicitly allowed to not be encrypted. From what it seems Rollbar does some operations in background and crashes when trying to access the file.

Stacktrace:

Fatal Exception: NSFileHandleOperationException
*** -[NSConcreteFileHandle readDataOfLength:]: Operation not permitted
-[RollbarFileReader readLine]

0  CoreFoundation                 0x1a7e0186c __exceptionPreprocess
1  libobjc.A.dylib                0x1bce1ac50 objc_exception_throw
2  Foundation                     0x1a90f27f4 -[NSConcreteFileHandle readDataUpToLength:error:]
3  Foundation                     0x1a908791c +[NSPropertyListSerialization writePropertyList:toStream:format:options:error:]
4  Rollbar                        0x107c34ec4 -[RollbarFileReader readLine] + 61 (RollbarFileReader.m:61)
5  Rollbar                        0x107c3508c -[RollbarFileReader enumerateLinesUsingBlock:] + 90 (RollbarFileReader.m:90)
6  Rollbar                        0x107c3773c -[RollbarNotifier processSavedItems] + 294 (RollbarNotifier.m:294)
7  Rollbar                        0x107c42aac -[RollbarThread checkItems] + 45 (RollbarThread.m:45)
8  Foundation                     0x1a9198b20 __NSFireTimer
9  CoreFoundation                 0x1a7d7dfa0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__
10 CoreFoundation                 0x1a7d7dba0 __CFRunLoopDoTimer
11 CoreFoundation                 0x1a7d7cffc __CFRunLoopDoTimers
12 CoreFoundation                 0x1a7d76ee4 __CFRunLoopRun
13 CoreFoundation                 0x1a7d7621c CFRunLoopRunSpecific
14 Foundation                     0x1a9025df0 -[NSRunLoop(NSRunLoop) runMode:beforeDate:]
15 Rollbar                        0x107c42be0 -[RollbarThread run] + 65 (RollbarThread.m:65)
16 Foundation                     0x1a9197a34 __NSThread__start__
17 libsystem_pthread.dylib        0x1f38abcb0 _pthread_start
18 libsystem_pthread.dylib        0x1f38b4778 thread_start

Device info:

Model: iPhone 12
Version: 14.4.2 (18D70)
App state: Backgrounded

@okalentiev , correct, the SDK uses 2 to 3 files (depending on configuration) to save its data temporarily in the background.

You can find out the location of the files by looking at RollbarCachesDirectory.directory property.
And the filenames of the files are:

static NSString *QUEUED_ITEMS_FILE_NAME = @"rollbar.items";
static NSString *STATE_FILE_NAME = @"rollbar.state";
static NSString *PAYLOADS_FILE_NAME = @"rollbar.payloads";

Also, the payloads' fully qualified path-filename can be overridden by following configuration object's property: logPayloadFile

@akornich Thanks for the clarificaiton.

The option here would be to disable data protection, but I don't really want to do that because logs are sensitive information. Is there a way to prevent Rollbar from doing any background file processing? Or this means that we are trying to log something in the background and it triggers Rollbar? I can queue logs while the app is in the background and send them after the app is awake, however, this sounds to me like a log library's responsibility.

Yes, in general, rollbar-ios initially stores the log entries made through it into a file (rollbar.items) and then processes the records in the file in the background whenever there is network connectivity to rollbar.com.
rollbar.state file is used for SDK internal bookkeeping while processing content of rollbar.items.
rollbar.payloads is only allocated and used optionally (normally for development purposes) in case you want to stash away locally any payload that went through the SDK instance.

@okalentiev , my bad, forgot to mention one more file maintained by the SDK: rollbar.telemetry.

@akornich Got it, thanks! So how would you suggest fixing the crash?

@okalentiev , didn't you say some files can be whitelisted so they are not expected to be encrypted?
We may also consider adding an option for the SDK-maintained files to be encrypted, but I would not be able to provide any timeline estimate for it right now.

@akornich Yes, however logs can contain sensitive information, and exposing them doesn't seem like the best solution.

@okalentiev , that is exactly why we have data scrubbing feature :).
In addition, you can also use custom payload transform to cover some cases that for example are not covered by the scrubbing.

@okalentiev , so, will the data scrubbing of unencrypted logs unblock you for now?

@akornich Yes, this should do the trick, for now. Thanks for the assistance.

@akornich I have disabled the data protection as per your suggestion, however, the app is still crashing. Did I do something wrong? Here is the code I used for this:

    private func excludeRollbarFromFileProtection() {
        guard let caches = FileManager.default.urls(for: .cachesDirectory,
                                                    in: .userDomainMask).first else {
            return
        }

        let rollbarCaches = [
            "rollbar.items",
            "rollbar.state",
            "rollbar.payloads",
            "rollbar.telemetry"
        ]

        for filename in rollbarCaches {
            do {
                try FileManager.default.setAttributes([.protectionKey: FileProtectionType.none],
                                                      ofItemAtPath: caches.appendingPathComponent(filename).path)
            } catch let error {
                self.error("Cannot remove data protection from the Rollbar files: \(error.localizedDescription)")
            }
        }
    }

I see that occasionally, the last two files are not present. Does it mean that they could be created later in the lifecycle of the app? I'm setting file permissions on the app startup right after Rollbar initialization. In this case, it could be that SDK tries to access files in the background, but I haven't got a chance to update the attributes. Any suggestions here?

@okalentiev , sorry, I somehow missed your last update posted here. Yes, the file I/O permissions/attributes have to be set before initializing the SDK. Some of the data files are allocated and used during the SDK initialization. The payloads and telemetry files are only used if developer logging and telemetry features are enabled.

closing due to no response