From 989862531ac85260f4ac1730fd5a7d3365b2c5a4 Mon Sep 17 00:00:00 2001 From: vlussenburg Date: Tue, 29 Nov 2022 10:49:29 -0800 Subject: [PATCH 01/14] redid crashloop detection branch without binaries --- .../src/main/cpp/backends/backend.cpp | 25 +++++++++++ .../main/cpp/backends/crashpad-backend.cpp | 43 +++++++++++++++++-- .../src/main/cpp/backtrace-native.cpp | 18 ++++++++ .../src/main/cpp/include/backend.h | 6 +++ .../src/main/cpp/include/crashpad-backend.h | 4 ++ .../library/base/BacktraceBase.java | 4 ++ .../backtraceio/backtraceio/MainActivity.java | 26 +++++++++-- .../src/main/res/layout/activity_main.xml | 8 +++- example-app/src/main/res/values/colors.xml | 1 + 9 files changed, 127 insertions(+), 8 deletions(-) diff --git a/backtrace-library/src/main/cpp/backends/backend.cpp b/backtrace-library/src/main/cpp/backends/backend.cpp index 0e8e4bf06..516b52a0c 100644 --- a/backtrace-library/src/main/cpp/backends/backend.cpp +++ b/backtrace-library/src/main/cpp/backends/backend.cpp @@ -82,4 +82,29 @@ void Disable() { "Disable not supported on this backend"); #endif } + +jboolean EnableCrashLoopDetectionBackend() { +#ifdef CRASHPAD_BACKEND + return EnableCrashLoopDetectionCrashpad(); +#elif BREAKPAD_BACKEND + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "EnableCrashLoopDetection not supported on this backend"); +#endif +} + +jboolean IsSafeModeRequiredBackend() { +#ifdef CRASHPAD_BACKEND + return IsSafeModeRequiredCrashpad(); +#elif BREAKPAD_BACKEND + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "IsSafeModeRequired not supported on this backend"); +#endif +} + +jint ConsecutiveCrashesCountBackend() { +#ifdef CRASHPAD_BACKEND + return ConsecutiveCrashesCountCrashpad(); +#elif BREAKPAD_BACKEND + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "ConsecutiveCrashesCount not supported on this backend"); +#endif +} + } \ No newline at end of file diff --git a/backtrace-library/src/main/cpp/backends/crashpad-backend.cpp b/backtrace-library/src/main/cpp/backends/crashpad-backend.cpp index 08cff7b1f..f316ccccb 100644 --- a/backtrace-library/src/main/cpp/backends/crashpad-backend.cpp +++ b/backtrace-library/src/main/cpp/backends/crashpad-backend.cpp @@ -3,6 +3,8 @@ #include #include +//#include "client/crashpad_client.h" + extern std::string thread_id; extern std::atomic_bool initialized; extern std::mutex attribute_synchronization; @@ -11,6 +13,8 @@ extern std::atomic_bool disabled; static crashpad::CrashpadClient *client; static std::unique_ptr database; +static int consecutive_crashes_count = 0; + bool InitializeCrashpad(jstring url, jstring database_path, jstring handler_path, @@ -19,6 +23,9 @@ bool InitializeCrashpad(jstring url, jobjectArray attachmentPaths, jboolean enableClientSideUnwinding, jint unwindingMode) { + + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Initialize Crashpad Start"); + // avoid multi initialization if (initialized) { __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Crashpad is already initialized"); @@ -120,9 +127,19 @@ bool InitializeCrashpad(jstring url, // Start crash handler client = new crashpad::CrashpadClient(); - - initialized = client->StartHandlerAtCrash(handler, db, db, backtraceUrl, attributes, - arguments); + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Crashpad created."); + client->EnableCrashLoopDetection(); + + // Get consecutive crashes count BEFORE any handler started, + // as it writes extra line into CSV, what leads to getting 0 for each next ConsecutiveCrashesCount call + consecutive_crashes_count = crashpad::CrashpadClient::ConsecutiveCrashesCount(db); + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Crashpad initialize - ConsecutiveCrashesCount %d", consecutive_crashes_count); +// initialized = client->StartHandler(handler, db, db, backtraceUrl, attributes, arguments, false, false); +// handler, db, db, url, annotations, arguments, false, false, {} +// Original + initialized = client->StartHandlerAtCrash(handler, db, db, backtraceUrl, attributes, arguments); + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Crashpad initialized %s", (initialized ? "TRUE" : "FALSE")); + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Crashpad db: %s", filePath); env->ReleaseStringUTFChars(url, backtraceUrl); env->ReleaseStringUTFChars(handler_path, handlerPath); @@ -219,10 +236,28 @@ void ReEnableCrashpad() { // Re-enable uploads if disabled if (disabled) { if (database == nullptr) { - __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Crashpad database is null, this should not happen"); + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", + "Crashpad database is null, this should not happen"); return; } database->GetSettings()->SetUploadsEnabled(true); disabled = false; } } + +bool EnableCrashLoopDetectionCrashpad() { + __android_log_print(ANDROID_LOG_ERROR, "Backtrace-Android", "Inside EnableCrashLoopDetectionCrashpad"); + if (client != nullptr) { + return client->EnableCrashLoopDetection(); + } else { + return false; + } +} + +bool IsSafeModeRequiredCrashpad() { + return consecutive_crashes_count >= 5; +} + +int ConsecutiveCrashesCountCrashpad() { + return consecutive_crashes_count; +} diff --git a/backtrace-library/src/main/cpp/backtrace-native.cpp b/backtrace-library/src/main/cpp/backtrace-native.cpp index eff318803..86436f681 100644 --- a/backtrace-library/src/main/cpp/backtrace-native.cpp +++ b/backtrace-library/src/main/cpp/backtrace-native.cpp @@ -135,4 +135,22 @@ Java_backtraceio_library_BacktraceDatabase_disable(JNIEnv *env, jobject thiz) { Disable(); } +extern "C" +JNIEXPORT jboolean JNICALL +Java_backtraceio_library_base_BacktraceBase_EnableCrashLoopDetectionBacktrace(JNIEnv *env, jclass clazz) { + return EnableCrashLoopDetectionBackend(); +} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_backtraceio_library_base_BacktraceBase_IsSafeModeRequiredBacktrace(JNIEnv *env, jclass clazz) { + return IsSafeModeRequiredBackend(); +} + +extern "C" +JNIEXPORT jint JNICALL +Java_backtraceio_library_base_BacktraceBase_ConsecutiveCrashesCountBacktrace(JNIEnv *env, jclass clazz) { + return ConsecutiveCrashesCountBackend(); +} + } diff --git a/backtrace-library/src/main/cpp/include/backend.h b/backtrace-library/src/main/cpp/include/backend.h index 3b0543e4c..3080f6a63 100644 --- a/backtrace-library/src/main/cpp/include/backend.h +++ b/backtrace-library/src/main/cpp/include/backend.h @@ -19,6 +19,12 @@ void DumpWithoutCrash(jstring message, jboolean set_main_thread_as_faulting_thre void AddAttribute(jstring key, jstring value); void Disable(); + +jboolean EnableCrashLoopDetectionBackend(); + +jboolean IsSafeModeRequiredBackend(); + +jint ConsecutiveCrashesCountBackend(); } #endif //BACKTRACE_ANDROID_BACKEND_H diff --git a/backtrace-library/src/main/cpp/include/crashpad-backend.h b/backtrace-library/src/main/cpp/include/crashpad-backend.h index 8a5c27eea..83340cd44 100644 --- a/backtrace-library/src/main/cpp/include/crashpad-backend.h +++ b/backtrace-library/src/main/cpp/include/crashpad-backend.h @@ -28,4 +28,8 @@ void DisableCrashpad(); void ReEnableCrashpad(); +bool EnableCrashLoopDetectionCrashpad(); +bool IsSafeModeRequiredCrashpad(); +int ConsecutiveCrashesCountCrashpad(); + #endif //BACKTRACE_ANDROID_CRASHPAD_BACKEND_H diff --git a/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java b/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java index ebb904a66..d6c7a2452 100644 --- a/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java +++ b/backtrace-library/src/main/java/backtraceio/library/base/BacktraceBase.java @@ -489,6 +489,10 @@ public void nativeCrash() { public native void dumpWithoutCrash(String message, boolean setMainThreadAsFaultingThread); + public static native boolean EnableCrashLoopDetectionBacktrace(); + public static native boolean IsSafeModeRequiredBacktrace(); + public static native int ConsecutiveCrashesCountBacktrace(); + /** * Sending an exception to Backtrace API * diff --git a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java index a9eaae111..bfd2fd2cb 100644 --- a/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java +++ b/example-app/src/main/java/backtraceio/backtraceio/MainActivity.java @@ -49,10 +49,30 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_main); // Set this value in your local.properties - if (BuildConfig.BACKTRACE_SUBMISSION_URL != null) { - backtraceClient = initializeBacktrace(BuildConfig.BACKTRACE_SUBMISSION_URL); - } + String BACKTRACE_SUBMISSION_URL = "https://submit.backtrace.io/konst-ryab/04aecb6b3da05e8d83f2a27f9b5f41352ac792428c5e5f6a94ff58d43ee14e46/json"; +// if (BACKTRACE_SUBMISSION_URL != null) { + backtraceClient = initializeBacktrace(BACKTRACE_SUBMISSION_URL); + Context context = getApplicationContext(); + String dbPath = context.getFilesDir().getAbsolutePath() + "/crashpad"; + + String csvPath = dbPath + "/crash_loop_detection.csv"; + File file = new File(csvPath); + Log.d("Backtrace-Android", "CSV file exists: " + (file.exists() ? "TRUE" : "FALSE")); + Log.d("Backtrace-Android", "DB path: " + dbPath); + Log.d("Backtrace-Android", "CSV path: " + csvPath); + + boolean isCLSafeModeReq = BacktraceClient.IsSafeModeRequiredBacktrace(); + int crashesCountCL = BacktraceClient.ConsecutiveCrashesCountBacktrace(); + Log.d("Backtrace-Android", "IsSafeModeRequiredCrashpad: " + isCLSafeModeReq); + Log.d("Backtrace-Android", "ConsecutiveCrashesCountCrashpad: " + crashesCountCL); + + View viewBackground = findViewById(R.id.viewBackground); + if(viewBackground != null) { + viewBackground.setBackgroundColor(isCLSafeModeReq + ? getResources().getColor(R.color.colorAccent) + : getResources().getColor(R.color.colorWhite)); + } symlinkAndWriteFile(); } diff --git a/example-app/src/main/res/layout/activity_main.xml b/example-app/src/main/res/layout/activity_main.xml index a12d05677..33933cb87 100644 --- a/example-app/src/main/res/layout/activity_main.xml +++ b/example-app/src/main/res/layout/activity_main.xml @@ -1,11 +1,17 @@ - +