Skip to content

Commit

Permalink
fix(crashlytics, ios): warn if debugger will break crashlytics
Browse files Browse the repository at this point in the history
debuggers intercept crashes in iOS, leading to developer confusion.
  • Loading branch information
mikehardy committed Apr 9, 2021
1 parent 6aea33f commit d6b6d23
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions packages/crashlytics/ios/RNFBCrashlytics/RNFBCrashlyticsModule.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
*
*/

#include <Foundation/Foundation.h>
#include <sys/sysctl.h>

#import <React/RCTUtils.h>
#import <React/RCTLog.h>

#import "RNFBCrashlyticsModule.h"
#import "RNFBCrashlyticsInitProvider.h"
Expand All @@ -33,6 +37,9 @@ - (NSDictionary *)constantsToExport {
NSMutableDictionary *constants = [NSMutableDictionary new];
constants[@"isCrashlyticsCollectionEnabled"] = @([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled])]);
constants[@"isErrorGenerationOnJSCrashEnabled"] = @([RCTConvert BOOL:@([RNFBCrashlyticsInitProvider isErrorGenerationOnJSCrashEnabled])]);
if ([self isDebuggerAttached]) {
RCTLog(@"@react-native-firebase/crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
}
return constants;
}

Expand All @@ -54,6 +61,10 @@ + (BOOL)requiresMainQueueSetup {

RCT_EXPORT_METHOD(crash) {
if ([RNFBCrashlyticsInitProvider isCrashlyticsCollectionEnabled]) {
if ([self isDebuggerAttached]) {
RCTLog(@"@react-native-firebase/crashlytics - WARNING: Debugger detected. Crashlytics will not receive crash reports.");
}

// https://firebase.google.com/docs/crashlytics/test-implementation?platform=ios recommends using "@[][1]" to crash,
// but that gets caught by react-native and shown as a red box for debug builds. Raise SIGSEGV here to generate a hard crash.
int *p = 0;
Expand Down Expand Up @@ -185,5 +196,37 @@ - (void)recordJavaScriptError:(NSDictionary *)jsErrorDict {
[[FIRCrashlytics crashlytics] recordExceptionModel:exceptionModel];
}

/**
* Check if the debugger is attached
*
* Taken from https://github.com/plausiblelabs/plcrashreporter/blob/2dd862ce049e6f43feb355308dfc710f3af54c4d/Source/Crash%20Demo/main.m#L96
*
* @return `YES` if the debugger is attached to the current process, `NO` otherwise
*/
- (BOOL)isDebuggerAttached {
static BOOL debuggerIsAttached = NO;

static dispatch_once_t debuggerPredicate;
dispatch_once(&debuggerPredicate, ^{
struct kinfo_proc info;
size_t info_size = sizeof(info);
int name[4];

name[0] = CTL_KERN;
name[1] = KERN_PROC;
name[2] = KERN_PROC_PID;
name[3] = getpid(); // from unistd.h, included by Foundation

if (sysctl(name, 4, &info, &info_size, NULL, 0) == -1) {
RCTLog(@"@react-native-firebase/crashlytics ERROR: Checking for a running debugger via sysctl() failed: %s", strerror(errno));
debuggerIsAttached = false;
}

if (!debuggerIsAttached && (info.kp_proc.p_flag & P_TRACED) != 0)
debuggerIsAttached = true;
});

return debuggerIsAttached;
}

@end

1 comment on commit d6b6d23

@vercel
Copy link

@vercel vercel bot commented on d6b6d23 Apr 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.