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

NSInvalidArgumentException BSGEventUploadOperation.m:112 #1138

Closed
tshedor opened this issue Jun 27, 2021 · 3 comments
Closed

NSInvalidArgumentException BSGEventUploadOperation.m:112 #1138

tshedor opened this issue Jun 27, 2021 · 3 comments
Labels
bug Confirmed bug released This feature/bug fix has been released

Comments

@tshedor
Copy link

tshedor commented Jun 27, 2021

Describe the bug

After upgrading from 6.2 to 6.9, we've been seeing unhandled crashes from a narrow set of users with the following stacktrace:

NSInvalidArgumentException: -[NSNull countByEnumeratingWithState:objects:count:]: unrecognized selector sent to instance 0x20a654a00

0  CoreFoundation          ___exceptionPreprocess
1  libobjc.A.dylib         _objc_exception_throw
2  CoreFoundation          -[NSObject(NSObject) doesNotRecognizeSelector:]
3  CoreFoundation          ____forwarding___
4  CoreFoundation          ___forwarding_prep_0___
5  Runner                  +[BugsnagError errorFromJson:] (BugsnagError.m:119:9)
6  Runner                  -[BugsnagEvent stacktraceTypes] (BugsnagEvent.m:729:31)
7  Runner                  -[BSGEventUploadOperation runWithDelegate:completionHandler:] (BSGEventUploadOperation.m:112:67)
8  Runner                  -[BSGEventUploadOperation start] (BSGEventUploadOperation.m:177:5)
9  Foundation              ___NSOPERATIONQUEUE_IS_STARTING_AN_OPERATION__
10 Foundation              ___NSOQSchedule_f
11 libdispatch.dylib       __dispatch_block_async_invoke2
12 libdispatch.dylib       __dispatch_client_callout
13 libdispatch.dylib       __dispatch_continuation_pop
14 libdispatch.dylib       __dispatch_async_redirect_invoke
15 libdispatch.dylib       __dispatch_root_queue_drain
16 libdispatch.dylib       __dispatch_worker_thread2
17 libsystem_pthread.dylib __pthread_wqthread
18 libsystem_pthread.dylib _start_wqthread

This is strange because the line in BugsnagError.m checks for nil values:

    if (trace != nil) {
        for (NSDictionary *dict in trace) {
            BugsnagStackframe *frame = [BugsnagStackframe frameFromJson:dict];

            if (frame != nil) {
                [data addObject:frame];
            }
        }
    }

From my limited knowledge of Obj-C, nil does not necessarily equal NSNull and a stricter comparison may be required for trace != nil. Or, since the use case utilizes a custom stack trace (see below), stricter validation may be required on the custom stack trace method.

Steps to reproduce

I maintain the bugsnag_flutter library (Flutter is a cross-platform mobile framework), which reports errors to the native SDK with an assigned a custom stacktrace for handled in-app events. This is done so that the errors receive the richness of the native SDK reporting (device version, user, breadcrumbs, etc). This is how the stack trace is assigned:

    NSException *exception = [NSException exceptionWithName:call.arguments[@"name"]
                                                     reason:call.arguments[@"description"] userInfo:nil];
    [Bugsnag notify:exception block:^BOOL(BugsnagEvent *event) {
      [event attachCustomStacktrace:call.arguments[@"stackTrace"]
                           withType:@"flutter"];
      [event addMetadata:@{@"Full Error": call.arguments[@"fullOutput"]} toSection:@"Flutter"];
      [event addMetadata:@{@"Context": call.arguments[@"context"]} toSection:@"Flutter"];
      if (call.arguments[@"additionalStackTrace"]) {
        [event addMetadata:@{@"StackTrace": call.arguments[@"additionalStackTrace"]} toSection:@"Flutter"];
      }

      return YES;
    }];

I'm still trying to figure out the sort of error that causes this failure and will provide better repro steps if/when they can be determined reliably.

Environment

  • Bugsnag version: 6.9.4
  • CocoaPods version: 1.10.1
  • Carthage version (if any): n/a
  • iOS/tvOS/macOS version(s):14.4.2
  • Simulator or physical device: Physical
  • Xcode version: 12.4
  • Swift version (if applicable): n/a
@tshedor
Copy link
Author

tshedor commented Jun 30, 2021

The unhandled errors are universally reported immediately after app start, which would indicate that custom stack trace errors that are stored before the next app launch (like in the event of a simultaneous OOM) are not stored with the BSGKeyStacktrace argument.

@nickdowell
Copy link
Contributor

Thanks for the detailed report and follow up! 👍

It appears that the crash is happening when trying to send an error that was stored by an earlier version (like 6.2) of Bugsnag. More recent versions (6.8.2 onwards) would throw an exception in -[BugsnagEvent attachCustomStacktrace:withType:] if passed an NSNull value and not get as far as storing the error.

bugsnag_flutter should check for nil and NSNull and prevent them being passed them to -[BugsnagEvent attachCustomStacktrace:withType:] since the API is defined as accepting a nonnull NSArray * (it must not be nil or another type).

Something like this:

id stacktrace = call.arguments[@"stackTrace"];
if ([stacktrace isKindOfClass:[NSArray class]]) {
   [event attachCustomStacktrace:stacktrace withType:@"flutter"];
}

It's fine to pass NSNull values to the addMetadata:... APIs.


+[BugsnagError errorFromJson:] will be fixed in a similar fashion to #1141 although we're going to make some further changes to improve the safety for other values at the same time.

@abigailbramble abigailbramble added backlog We hope to fix this feature/bug in the future bug Confirmed bug labels Jun 30, 2021
@mattdyoung
Copy link

Fixed in v6.10.1

@mattdyoung mattdyoung added released This feature/bug fix has been released and removed backlog We hope to fix this feature/bug in the future labels Jul 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Confirmed bug released This feature/bug fix has been released
Projects
None yet
Development

No branches or pull requests

4 participants