mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-22 10:46:50 +00:00
Render better crash stack traces for executors.
This commit is contained in:
@@ -7,9 +7,9 @@ import androidx.annotation.NonNull;
|
||||
import net.zetetic.database.DatabaseErrorHandler;
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||
|
||||
import org.signal.core.util.ExceptionUtil;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.util.CursorUtil;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
/**
|
||||
* The default error handler wipes the file. This one instead prints some diagnostics and then crashes so the original corrupt file isn't lost.
|
||||
@@ -45,7 +45,7 @@ public final class SqlCipherErrorHandler implements DatabaseErrorHandler {
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
output.append("Failed to do integrity_check!").append("\n")
|
||||
.append(Util.convertThrowableToString(t));
|
||||
.append(ExceptionUtil.convertThrowableToString(t));
|
||||
}
|
||||
|
||||
output.append("\n").append("===== PRAGMA cipher_integrity_check =====").append("\n");
|
||||
@@ -56,7 +56,7 @@ public final class SqlCipherErrorHandler implements DatabaseErrorHandler {
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
output.append("Failed to do cipher_integrity_check!").append("\n")
|
||||
.append(Util.convertThrowableToString(t));
|
||||
.append(ExceptionUtil.convertThrowableToString(t));
|
||||
}
|
||||
|
||||
Log.e(TAG, output.toString());
|
||||
|
||||
@@ -58,7 +58,7 @@ public class JobManager implements ConstraintObserver.Notifier {
|
||||
public JobManager(@NonNull Application application, @NonNull Configuration configuration) {
|
||||
this.application = application;
|
||||
this.configuration = configuration;
|
||||
this.executor = new FilteredExecutor(configuration.getExecutorFactory().newSingleThreadExecutor("signal-JobManager"), ThreadUtil::isMainThread);
|
||||
this.executor = ThreadUtil.trace(new FilteredExecutor(configuration.getExecutorFactory().newSingleThreadExecutor("signal-JobManager"), ThreadUtil::isMainThread));
|
||||
this.jobTracker = configuration.getJobTracker();
|
||||
this.jobController = new JobController(application,
|
||||
configuration.getJobStorage(),
|
||||
|
||||
@@ -7,12 +7,12 @@ import android.os.Handler;
|
||||
import androidx.annotation.MainThread;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import org.signal.core.util.ExceptionUtil;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.thoughtcrime.securesms.notifications.v2.MessageNotifierV2;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.BubbleUtil;
|
||||
import org.thoughtcrime.securesms.util.LeakyBucketLimiter;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
/**
|
||||
* Uses a leaky-bucket strategy to limiting notification updates.
|
||||
@@ -109,7 +109,7 @@ public class OptimizedMessageNotifier implements MessageNotifier {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (RuntimeException e) {
|
||||
throw Util.appendStackTrace(e, prettyException);
|
||||
throw ExceptionUtil.joinStackTrace(e, prettyException);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import androidx.annotation.NonNull;
|
||||
|
||||
import net.zetetic.database.sqlcipher.SQLiteDatabase;
|
||||
|
||||
import org.signal.core.util.ThreadUtil;
|
||||
import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.concurrent.TracingExecutorService;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.DatabaseFactory;
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase;
|
||||
@@ -28,7 +30,6 @@ import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -60,7 +61,7 @@ public final class LiveRecipientCache {
|
||||
this.localRecipientId = new AtomicReference<>(null);
|
||||
this.unknown = new LiveRecipient(context, Recipient.UNKNOWN);
|
||||
this.db = DatabaseFactory.getInstance(context).getRawDatabase();
|
||||
this.resolveExecutor = new FilteredExecutor(SignalExecutors.BOUNDED, () -> !db.inTransaction());
|
||||
this.resolveExecutor = ThreadUtil.trace(new FilteredExecutor(SignalExecutors.BOUNDED, () -> !db.inTransaction()));
|
||||
}
|
||||
|
||||
@AnyThread
|
||||
@@ -83,16 +84,7 @@ public final class LiveRecipientCache {
|
||||
}
|
||||
|
||||
if (needsResolve) {
|
||||
final LiveRecipient toResolve = live;
|
||||
|
||||
MissingRecipientException prettyStackTraceError = new MissingRecipientException(toResolve.getId());
|
||||
resolveExecutor.execute(() -> {
|
||||
try {
|
||||
toResolve.resolve();
|
||||
} catch (MissingRecipientException e) {
|
||||
throw prettyStackTraceError;
|
||||
}
|
||||
});
|
||||
resolveExecutor.execute(live::resolve);
|
||||
}
|
||||
|
||||
return live;
|
||||
|
||||
@@ -515,31 +515,4 @@ public class Util {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the stack trace of the provided throwable onto the provided primary exception. This is
|
||||
* useful for when exceptions are thrown inside of asynchronous systems (like runnables in an
|
||||
* executor) where you'd otherwise lose important parts of the stack trace. This lets you save a
|
||||
* throwable at the entry point, and then combine it with any caught exceptions later.
|
||||
*
|
||||
* @return The provided primary exception, for convenience.
|
||||
*/
|
||||
public static RuntimeException appendStackTrace(@NonNull RuntimeException primary, @NonNull Throwable secondary) {
|
||||
StackTraceElement[] now = primary.getStackTrace();
|
||||
StackTraceElement[] then = secondary.getStackTrace();
|
||||
StackTraceElement[] combined = new StackTraceElement[now.length + then.length];
|
||||
|
||||
System.arraycopy(now, 0, combined, 0, now.length);
|
||||
System.arraycopy(then, 0, combined, now.length, then.length);
|
||||
|
||||
primary.setStackTrace(combined);
|
||||
|
||||
return primary;
|
||||
}
|
||||
|
||||
public static @NonNull String convertThrowableToString(@NonNull Throwable throwable) {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
throwable.printStackTrace(new PrintStream(outputStream));
|
||||
return outputStream.toString();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user