From 6b60adc079f2cdf05c94df72299a1df41e4422c6 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Sun, 17 Apr 2022 05:54:45 +0500 Subject: [PATCH] Fixed: Do not stop the app if `UncaughtExceptionHandler` implemented by `CrashHandler` receives an exception on a non main thread Rename function that should be used by main thread of apps to `setDefaultCrashHandler()`. Functions for other threads will be added in a later commit. --- .../com/termux/app/TermuxApplication.java | 2 +- .../com/termux/shared/crash/CrashHandler.java | 34 +++++++++++-------- .../shared/termux/crash/TermuxCrashUtils.java | 8 +++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/com/termux/app/TermuxApplication.java b/app/src/main/java/com/termux/app/TermuxApplication.java index 17f690a2..bf088758 100644 --- a/app/src/main/java/com/termux/app/TermuxApplication.java +++ b/app/src/main/java/com/termux/app/TermuxApplication.java @@ -20,7 +20,7 @@ public class TermuxApplication extends Application { Context context = getApplicationContext(); // Set crash handler for the app - TermuxCrashUtils.setCrashHandler(this); + TermuxCrashUtils.setDefaultCrashHandler(this); // Set log config for the app setLogConfig(context); diff --git a/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java b/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java index 79309f24..44422afe 100644 --- a/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java +++ b/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java @@ -19,28 +19,34 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { private final Context mContext; private final CrashHandlerClient mCrashHandlerClient; - private final Thread.UncaughtExceptionHandler defaultUEH; + private final Thread.UncaughtExceptionHandler mDefaultUEH; + private final boolean mIsDefaultHandler; private static final String LOG_TAG = "CrashUtils"; - private CrashHandler(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient) { - this.mContext = context; - this.mCrashHandlerClient = crashHandlerClient; - this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); + private CrashHandler(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient, + boolean isDefaultHandler) { + mContext = context; + mCrashHandlerClient = crashHandlerClient; + mDefaultUEH = Thread.getDefaultUncaughtExceptionHandler(); + mIsDefaultHandler = isDefaultHandler; } public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) { Logger.logInfo(LOG_TAG, "uncaughtException() for " + thread + ": " + throwable.getMessage()); logCrash(thread, throwable); - defaultUEH.uncaughtException(thread, throwable); + + // Don't stop the app if not on the main thread + if (mIsDefaultHandler) + mDefaultUEH.uncaughtException(thread, throwable); } /** - * Set default uncaught crash handler of current thread to {@link CrashHandler}. + * Set default uncaught crash handler for the app to {@link CrashHandler}. */ - public static void setCrashHandler(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient) { + public static void setDefaultCrashHandler(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient) { if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CrashHandler)) { - Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(context, crashHandlerClient)); + Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(context, crashHandlerClient, true)); } } @@ -56,7 +62,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { @NonNull CrashHandlerClient crashHandlerClient, @NonNull Thread thread, @NonNull Throwable throwable) { Logger.logInfo(LOG_TAG, "logCrash() for " + thread + ": " + throwable.getMessage()); - new CrashHandler(context, crashHandlerClient).logCrash(thread, throwable); + new CrashHandler(context, crashHandlerClient, false).logCrash(thread, throwable); } public void logCrash(@NonNull Thread thread, @NonNull Throwable throwable) { @@ -99,7 +105,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { /** * Called before {@link #logCrashToFile(Context, CrashHandlerClient, Thread, Throwable)} is called. * - * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient)}. + * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient, boolean)}. * @param thread The {@link Thread} in which the crash happened. * @param throwable The {@link Throwable} thrown for the crash. * @return Should return {@code true} if crash has been handled and should not be logged, @@ -110,7 +116,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { /** * Called after {@link #logCrashToFile(Context, CrashHandlerClient, Thread, Throwable)} is called. * - * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient)}. + * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient, boolean)}. * @param thread The {@link Thread} in which the crash happened. * @param throwable The {@link Throwable} thrown for the crash. */ @@ -119,7 +125,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { /** * Get crash log file path. * - * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient)}. + * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient, boolean)}. * @return Should return the crash log file path. */ @NonNull @@ -128,7 +134,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { /** * Get app info markdown string to add to crash log. * - * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient)}. + * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient, boolean)}. * @return Should return app info markdown string. */ String getAppInfoMarkdownString(Context context); diff --git a/termux-shared/src/main/java/com/termux/shared/termux/crash/TermuxCrashUtils.java b/termux-shared/src/main/java/com/termux/shared/termux/crash/TermuxCrashUtils.java index 0742c700..5ac9225e 100644 --- a/termux-shared/src/main/java/com/termux/shared/termux/crash/TermuxCrashUtils.java +++ b/termux-shared/src/main/java/com/termux/shared/termux/crash/TermuxCrashUtils.java @@ -48,8 +48,12 @@ public class TermuxCrashUtils implements CrashHandler.CrashHandlerClient { } /** - * Set default uncaught crash handler of current thread to {@link CrashHandler} for Termux app - * and its plugin to log crashes at {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}. + * Set default uncaught crash handler of the app to {@link CrashHandler} for Termux app + * and its plugins to log crashes at {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}. + */ + public static void setDefaultCrashHandler(@NonNull final Context context) { + CrashHandler.setDefaultCrashHandler(context, new TermuxCrashUtils(TYPE.UNCAUGHT_EXCEPTION)); + } */ public static void setCrashHandler(@NonNull final Context context) { CrashHandler.setCrashHandler(context, new TermuxCrashUtils(TYPE.UNCAUGHT_EXCEPTION));