diff --git a/examples/default/android/app/build.gradle b/examples/default/android/app/build.gradle index e0bd64bfbf..6ff938b570 100644 --- a/examples/default/android/app/build.gradle +++ b/examples/default/android/app/build.gradle @@ -156,6 +156,12 @@ android { } } + externalNativeBuild { + cmake { + path file('src/main/cpp/CMakeLists.txt') + version '3.22.1' + } + } } dependencies { diff --git a/examples/default/android/app/src/main/cpp/CMakeLists.txt b/examples/default/android/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000..93f7d550c7 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,52 @@ + +# For more information about using CMake with Android Studio, read the +# documentation: https://d.android.com/studio/projects/add-native-code.html. +# For more examples on how to use CMake, see https://github.com/android/ndk-samples. + +# Sets the minimum CMake version required for this project. +cmake_minimum_required(VERSION 3.22.1) + +# Declares the project name. The project name can be accessed via ${ PROJECT_NAME}, +# Since this is the top level CMakeLists.txt, the project name is also accessible +# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level +# build script scope). +project("native-lib") + +# Creates and names a library, sets it as either STATIC +# or SHARED, and provides the relative paths to its source code. +# You can define multiple libraries, and CMake builds them for you. +# Gradle automatically packages shared libraries with your APK. +# +# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define +# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME} +# is preferred for the same purpose. +# +# In order to load a library into your app from Java/Kotlin, you must call +# System.loadLibrary() and pass the name of the library defined here; +# for GameActivity/NativeActivity derived applications, the same library name must be +# used in the AndroidManifest.xml file. +add_library(${CMAKE_PROJECT_NAME} SHARED + # List C/C++ source files with relative paths to this CMakeLists.txt. + native-lib.cpp + crasher.c + crasher_2.c + crasher_3.c + crasher_4.cpp + ) +find_library( # Sets the name of the path variable. + log-lib + + # Specifies the name of the NDK library that + # you want CMake to locate. + log) + + +# Specifies libraries CMake should link to your target library. You +# can link libraries from various origins, such as libraries defined in this +# build script, prebuilt third-party libraries, or Android system libraries. +target_link_libraries(${CMAKE_PROJECT_NAME} + # List libraries link to the target library + android + log + ${log-lib} + ) diff --git a/examples/default/android/app/src/main/cpp/crasher.c b/examples/default/android/app/src/main/cpp/crasher.c new file mode 100644 index 0000000000..a47f3c1b12 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher.c @@ -0,0 +1,50 @@ + +#include +#include +#include +#include +#include "crasher_2.h" + +/************* SIGSEGV *******************************/ +JNIEXPORT void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_causeSIGSEGVCrash(JNIEnv *env, jobject thiz) { + causeSIGSEGVCrashF1(); +} + +/*****************************************************/ + +/************* SIGABRT *******************************/ +void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_causeSIGABRTCrash(JNIEnv *env, jobject thiz) { + causeSIGABRTCrashF1(); +} +/****************************************************/ + +/************* SIGFPE *******************************/ +void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_causeSIGFPECrash(JNIEnv *env, jobject thiz) { + causeSIGFPECrashF1(); +} +/***************************************************/ + +/************* SIGILL *******************************/ + +void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_causeSIGILLCrash(JNIEnv *env, jobject thiz) { + causeSIGILLCrashF1(); +} +/***************************************************/ + +/************* SIGBUS *******************************/ +void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_causeSIGBUSCrash(JNIEnv *env, jobject thiz) { + causeSIGBUSCrashF1(); +} +/***************************************************/ + +/************* SIGTRAP *******************************/ +void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_causeSIGTRAPCrash(JNIEnv *env, jobject thiz) { + causeSIGTRAPCrashF1(); +} +/***************************************************/ diff --git a/examples/default/android/app/src/main/cpp/crasher_2.c b/examples/default/android/app/src/main/cpp/crasher_2.c new file mode 100644 index 0000000000..5aac24df83 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher_2.c @@ -0,0 +1,47 @@ + + +#include +#include +#include +#include +#include "crasher_3.h" + +/************* SIGSEGV *******************************/ +void causeSIGSEGVCrashF1() { + causeSIGSEGVCrashF2(); +} +/*****************************************************/ + +/************* SIGABRT *******************************/ +void causeSIGABRTCrashF1() { + causeSIGABRTCrashF2(); +} +/****************************************************/ + +/************* SIGFPE *******************************/ + + +void causeSIGFPECrashF1() { + causeSIGFPECrashF2(); +} +/***************************************************/ + +/************* SIGILL *******************************/ + +void causeSIGILLCrashF1() { + causeSIGILLCrashF2(); +} +/***************************************************/ + +/************* SIGBUS *******************************/ + +void causeSIGBUSCrashF1() { + causeSIGBUSCrashF2(); +} +/***************************************************/ + +/************* SIGTRAP *******************************/ +void causeSIGTRAPCrashF1() { + causeSIGTRAPCrashF2(); +} +/***************************************************/ diff --git a/examples/default/android/app/src/main/cpp/crasher_2.h b/examples/default/android/app/src/main/cpp/crasher_2.h new file mode 100644 index 0000000000..d435af0576 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher_2.h @@ -0,0 +1,58 @@ + + +/************* SIGSEGV *******************************/ +void causeSIGSEGVCrashF3(); + +void causeSIGSEGVCrashF2(); + +void causeSIGSEGVCrashF1(); + +/*****************************************************/ + +/************* SIGABRT *******************************/ +void causeSIGABRTCrashF3(); + +void causeSIGABRTCrashF2(); + +void causeSIGABRTCrashF1(); + +/****************************************************/ + +/************* SIGFPE *******************************/ + +int causeSIGFPECrashF3(); + +void causeSIGFPECrashF2(); + +void causeSIGFPECrashF1(); + +/***************************************************/ + +/************* SIGILL *******************************/ + +void causeSIGILLCrashF3(); + +void causeSIGILLCrashF2(); + +void causeSIGILLCrashF1(); + +/***************************************************/ + +/************* SIGBUS *******************************/ + +void causeSIGBUSCrashF3(); + +void causeSIGBUSCrashF2(); + +void causeSIGBUSCrashF1(); + +/***************************************************/ + +/************* SIGTRAP *******************************/ + +void causeSIGTRAPCrashF3(); + +void causeSIGTRAPCrashF2(); + +void causeSIGTRAPCrashF1(); +/***************************************************/ diff --git a/examples/default/android/app/src/main/cpp/crasher_3.c b/examples/default/android/app/src/main/cpp/crasher_3.c new file mode 100644 index 0000000000..c53f5fbc86 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher_3.c @@ -0,0 +1,44 @@ + +#pragma GCC optimize ("O0") +#include +#include +#include +#include +#include "crasher_4.h" + +/************* SIGSEGV *******************************/ +void causeSIGSEGVCrashF2() { + causeSIGSEGVCrashF3(NULL); +} +/*****************************************************/ + +/************* SIGABRT *******************************/ +void causeSIGABRTCrashF2() { + causeSIGABRTCrashF3(); +} +/****************************************************/ + +/************* SIGFPE *******************************/ +void causeSIGFPECrashF2() { + unsigned int *bad_pointer = (unsigned int *)(0xdeadbeef); + *bad_pointer=0xfeedface; +} +/***************************************************/ + +/************* SIGILL *******************************/ +void causeSIGILLCrashF2() { + causeSIGILLCrashF3(); +} +/***************************************************/ + +/************* SIGBUS *******************************/ +void causeSIGBUSCrashF2() { + causeSIGBUSCrashF3(); +} +/***************************************************/ + +/************* SIGTRAP *******************************/ +void causeSIGTRAPCrashF2() { + causeSIGTRAPCrashF3(); +} +/***************************************************/ diff --git a/examples/default/android/app/src/main/cpp/crasher_3.h b/examples/default/android/app/src/main/cpp/crasher_3.h new file mode 100644 index 0000000000..ed40396124 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher_3.h @@ -0,0 +1,24 @@ + +/************* SIGSEGV *******************************/ +void causeSIGSEGVCrashF2(); +/*****************************************************/ + +/************* SIGABRT *******************************/ +void causeSIGABRTCrashF2(); +/****************************************************/ + +/************* SIGFPE *******************************/ +void causeSIGFPECrashF2(); +/***************************************************/ + +/************* SIGILL *******************************/ +void causeSIGILLCrashF2(); +/***************************************************/ + +/************* SIGBUS *******************************/ +void causeSIGBUSCrashF2(); +/***************************************************/ + +/************* SIGTRAP *******************************/ +void causeSIGTRAPCrashF2(); +/***************************************************/ diff --git a/examples/default/android/app/src/main/cpp/crasher_4.cpp b/examples/default/android/app/src/main/cpp/crasher_4.cpp new file mode 100644 index 0000000000..1b59db3a99 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher_4.cpp @@ -0,0 +1,57 @@ + + +#include +#include +#include +#include +#include + +extern "C" { +/************* SIGSEGV *******************************/ +void causeSIGSEGVCrashF3(volatile int *i) { + //SIGSEGV + volatile int j = 34 / *i; +} +/*****************************************************/ + +/************* SIGABRT *******************************/ +void causeSIGABRTCrashF3() { + //SIGABRT + throw std::invalid_argument("received invalid value"); +} +/****************************************************/ + +/************* SIGFPE *******************************/ +void causeSIGFPECrashF3() { + //SIGFPE + raise(SIGFPE); + pthread_kill(getpid(), SIGFPE); +} +/***************************************************/ + +/************* SIGILL *******************************/ + +int causeSIGILLCrashF3() { + //SIGILL + raise(SIGILL); + pthread_kill(getpid(), SIGILL); +} +/***************************************************/ + +/************* SIGBUS *******************************/ + +void causeSIGBUSCrashF3() { + //SIGBUS + raise(SIGBUS); + pthread_kill(getpid(), SIGBUS); +} +/***************************************************/ + +/************* SIGTRAP *******************************/ + +void causeSIGTRAPCrashF3() { + //SIGBUS + __builtin_trap(); +} +/***************************************************/ +} diff --git a/examples/default/android/app/src/main/cpp/crasher_4.h b/examples/default/android/app/src/main/cpp/crasher_4.h new file mode 100644 index 0000000000..8c546ee040 --- /dev/null +++ b/examples/default/android/app/src/main/cpp/crasher_4.h @@ -0,0 +1,24 @@ + +/************* SIGSEGV *******************************/ +void causeSIGSEGVCrashF3(int* i); +/*****************************************************/ + +/************* SIGABRT *******************************/ +void causeSIGABRTCrashF3(); +/****************************************************/ + +/************* SIGFPE *******************************/ +void causeSIGFPECrashF3(); +/***************************************************/ + +/************* SIGILL *******************************/ +int causeSIGILLCrashF3(); +/***************************************************/ + +/************* SIGBUS *******************************/ +void causeSIGBUSCrashF3(); +/***************************************************/ + +/************* SIGTRAP *******************************/ +void causeSIGTRAPCrashF3(); +/***************************************************/ diff --git a/examples/default/android/app/src/main/cpp/native-lib.cpp b/examples/default/android/app/src/main/cpp/native-lib.cpp new file mode 100644 index 0000000000..29a84a5dca --- /dev/null +++ b/examples/default/android/app/src/main/cpp/native-lib.cpp @@ -0,0 +1,19 @@ +#include +#include +#include + + + + +/* + * Throws invalid argument exception + */ +extern "C" +JNIEXPORT void JNICALL +Java_com_instabug_react_example_nativeLibs_CppNativeLib_crashNDK(JNIEnv *env, + jobject object) { + __android_log_print(ANDROID_LOG_DEBUG, "NativeC++", "%s", "received invalid value"); + + // in Android SDK it's equivalent to causeSIGABRTCrash() + throw std::invalid_argument("received invalid value"); +} \ No newline at end of file diff --git a/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java b/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java index 7f748ad9f8..96769ed5dc 100644 --- a/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java +++ b/examples/default/android/app/src/main/java/com/instabug/react/example/RNInstabugExampleCrashReportingModule.java @@ -9,6 +9,7 @@ import com.instabug.crash.CrashReporting; import com.instabug.crash.models.IBGNonFatalException; import com.instabug.library.Feature; +import com.instabug.react.example.nativeLibs.CppNativeLib; import com.instabug.reactlibrary.RNInstabugReactnativeModule; import com.instabug.reactlibrary.utils.MainThreadHandler; @@ -71,6 +72,43 @@ public void sendOOM() { oomCrash(); } + ////////////////////// NDK SECTION ////////////////////////// + @ReactMethod + public void sendNDKCrash() { + CppNativeLib.crashNDK(); + } + + @ReactMethod + public void causeSIGSEGVCrash() { + CppNativeLib.causeSIGSEGVCrash(); + } + + @ReactMethod + public void causeSIGABRTCrash() { + CppNativeLib.causeSIGABRTCrash(); + } + + @ReactMethod + public void causeSIGFPECrash() { + CppNativeLib.causeSIGFPECrash(); + } + + @ReactMethod + public void causeSIGILLCrash() { + CppNativeLib.causeSIGILLCrash(); + } + + @ReactMethod + public void causeSIGBUSCrash() { + CppNativeLib.causeSIGBUSCrash(); + } + + @ReactMethod + public void causeSIGTRAPCrash() { + CppNativeLib.causeSIGTRAPCrash(); + } + + private void oomCrash() { new Thread(() -> { List stringList = new ArrayList<>(); diff --git a/examples/default/android/app/src/main/java/com/instabug/react/example/nativeLibs/CppNativeLib.java b/examples/default/android/app/src/main/java/com/instabug/react/example/nativeLibs/CppNativeLib.java new file mode 100644 index 0000000000..ac4ad60d1b --- /dev/null +++ b/examples/default/android/app/src/main/java/com/instabug/react/example/nativeLibs/CppNativeLib.java @@ -0,0 +1,24 @@ +package com.instabug.react.example.nativeLibs; + +/** + * C++ Native library bridge. + */ +public class CppNativeLib { + + static { + System.loadLibrary("native-lib"); + } + + /** + * Crashes the app with an invalid argument exception in the C++ native library. + */ + public static native void crashNDK(); + public static native void causeSIGSEGVCrash(); + public static native void causeSIGABRTCrash(); + public static native void causeSIGFPECrash(); + public static native void causeSIGILLCrash(); + public static native void causeSIGBUSCrash(); + public static native void causeSIGTRAPCrash(); + + +} diff --git a/examples/default/ios/Podfile.lock b/examples/default/ios/Podfile.lock index 14e850a393..28ea23051a 100644 --- a/examples/default/ios/Podfile.lock +++ b/examples/default/ios/Podfile.lock @@ -74,6 +74,9 @@ PODS: - hermes-engine/Pre-built (= 0.72.3) - hermes-engine/Pre-built (0.72.3) - Instabug (12.7.0) + - instabug-reactnative-ndk (0.1.0): + - RCT-Folly (= 2021.07.22.00) + - React-Core - libevent (2.1.12) - OCMock (3.9.3) - OpenSSL-Universal (1.1.1100) @@ -565,6 +568,7 @@ DEPENDENCIES: - FlipperKit/SKIOSNetworkPlugin (= 0.182.0) - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) + - instabug-reactnative-ndk (from `../node_modules/instabug-reactnative-ndk`) - libevent (~> 2.1.12) - OCMock - OpenSSL-Universal (= 1.1.1100) @@ -645,6 +649,8 @@ EXTERNAL SOURCES: hermes-engine: :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" :tag: hermes-2023-03-20-RNv0.72.0-49794cfc7c81fb8f69fd60c3bbf85a7480cc5a77 + instabug-reactnative-ndk: + :path: "../node_modules/instabug-reactnative-ndk" RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTRequired: @@ -746,6 +752,7 @@ SPEC CHECKSUMS: glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322 Instabug: 59f0b0bc2c062b5cdbbf417cca365480a1fe55d8 + instabug-reactnative-ndk: 960119a69380cf4cbe47ccd007c453f757927d17 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 OCMock: 300b1b1b9155cb6378660b981c2557448830bdc6 OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c diff --git a/examples/default/package.json b/examples/default/package.json index 608dd04396..1125465570 100644 --- a/examples/default/package.json +++ b/examples/default/package.json @@ -23,7 +23,8 @@ "react-native-safe-area-context": "^4.5.3", "react-native-screens": "^3.20.0", "react-native-svg": "^13.9.0", - "react-native-vector-icons": "^10.0.0" + "react-native-vector-icons": "^10.0.0", + "instabug-reactnative-ndk": "github:https://github.com/Instabug/Instabug-React-Native-NDK" }, "devDependencies": { "@babel/core": "^7.20.0", diff --git a/examples/default/src/App.tsx b/examples/default/src/App.tsx index 7f302c5d1e..4bc1447056 100644 --- a/examples/default/src/App.tsx +++ b/examples/default/src/App.tsx @@ -3,7 +3,12 @@ import { StyleSheet } from 'react-native'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { NavigationContainer } from '@react-navigation/native'; -import Instabug, { InvocationEvent, LogLevel, ReproStepsMode } from 'instabug-reactnative'; +import Instabug, { + CrashReporting, + InvocationEvent, + LogLevel, + ReproStepsMode, +} from 'instabug-reactnative'; import { NativeBaseProvider } from 'native-base'; import { RootTabNavigator } from './navigation/RootTab'; @@ -17,6 +22,7 @@ export const App: React.FC = () => { invocationEvents: [InvocationEvent.floatingButton], debugLogsLevel: LogLevel.verbose, }); + CrashReporting.setNDKCrashesEnabled(true); Instabug.setReproStepsConfig({ all: ReproStepsMode.enabled, diff --git a/examples/default/src/native/NativeCrashReporting.ts b/examples/default/src/native/NativeCrashReporting.ts index a64f4526dd..bac4d0b67b 100644 --- a/examples/default/src/native/NativeCrashReporting.ts +++ b/examples/default/src/native/NativeCrashReporting.ts @@ -8,6 +8,20 @@ export interface CrashReportingExampleNativeModule extends NativeModule { sendFatalHang(): Promise; sendANR(): Promise; sendOOM(): Promise; + + sendNDKCrash(): Promise; + + causeSIGSEGVCrash(): Promise; + + causeSIGABRTCrash(): Promise; + + causeSIGFPECrash(): Promise; + + causeSIGILLCrash(): Promise; + + causeSIGBUSCrash(): Promise; + + causeSIGTRAPCrash(): Promise; } export const NativeExampleCrashReporting = NativeExampleModules.CrashReportingExampleModule; diff --git a/examples/default/src/screens/CrashReportingScreen.tsx b/examples/default/src/screens/CrashReportingScreen.tsx index eeb1b6f18a..24eae5113d 100644 --- a/examples/default/src/screens/CrashReportingScreen.tsx +++ b/examples/default/src/screens/CrashReportingScreen.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Alert, ScrollView, Text } from 'react-native'; +import { Alert, Platform, ScrollView, Text, View } from 'react-native'; import { CrashReporting } from 'instabug-reactnative'; @@ -120,6 +120,50 @@ export const CrashReportingScreen: React.FC = () => { onPress={() => NativeExampleCrashReporting.sendOOM()} /> + {Platform.OS === 'android' ? ( +
+ NDK Crashes can only be tested in release mode + These buttons will crash the application. + { + console.log('Sending NDK SIGSEGV Crash'); + await NativeExampleCrashReporting.causeSIGSEGVCrash(); + }} + /> + { + console.log('Sending NDK SIGFPE Crash'); + await NativeExampleCrashReporting.causeSIGFPECrash(); + }} + /> + { + console.log('Sending NDK SIGILL Crash'); + await NativeExampleCrashReporting.causeSIGILLCrash(); + }} + /> + + { + console.log('Sending NDK SIGBUS Crash'); + await NativeExampleCrashReporting.causeSIGBUSCrash(); + }} + /> + { + console.log('Sending NDK SIGTRAP Crash'); + await NativeExampleCrashReporting.causeSIGTRAPCrash(); + }} + /> +
+ ) : ( + + )} ); diff --git a/examples/default/yarn.lock b/examples/default/yarn.lock index f036714d72..6830582154 100644 --- a/examples/default/yarn.lock +++ b/examples/default/yarn.lock @@ -4459,6 +4459,10 @@ inline-style-prefixer@^6.0.1: css-in-js-utils "^3.1.0" fast-loops "^1.1.3" +"instabug-reactnative-ndk@github:https://github.com/Instabug/Instabug-React-Native-NDK": + version "0.1.0" + resolved "https://codeload.github.com/Instabug/Instabug-React-Native-NDK/tar.gz/3b0bac281253133852d32f52aa50cc805dd0b570" + "instabug-reactnative@link:../..": version "0.0.0" uid ""