431 lines
18 KiB
Java
431 lines
18 KiB
Java
package com.tencent.bugly.crashreport.crash;
|
|
|
|
import android.content.Context;
|
|
import android.os.Process;
|
|
import com.tencent.bugly.crashreport.common.strategy.StrategyBean;
|
|
import com.tencent.bugly.proguard.x;
|
|
import com.tencent.bugly.proguard.y;
|
|
import com.tencent.bugly.proguard.z;
|
|
import java.lang.Thread;
|
|
import java.util.HashMap;
|
|
|
|
/* compiled from: BUGLY */
|
|
/* loaded from: classes.dex */
|
|
public final class e implements Thread.UncaughtExceptionHandler {
|
|
private static String h;
|
|
private static final Object i = new Object();
|
|
private Context a;
|
|
private b b;
|
|
private com.tencent.bugly.crashreport.common.strategy.a c;
|
|
private com.tencent.bugly.crashreport.common.info.a d;
|
|
private Thread.UncaughtExceptionHandler e;
|
|
private Thread.UncaughtExceptionHandler f;
|
|
private boolean g = false;
|
|
private int j;
|
|
|
|
public e(Context context, b bVar, com.tencent.bugly.crashreport.common.strategy.a aVar, com.tencent.bugly.crashreport.common.info.a aVar2) {
|
|
this.a = context;
|
|
this.b = bVar;
|
|
this.c = aVar;
|
|
this.d = aVar2;
|
|
}
|
|
|
|
public final synchronized void a() {
|
|
if (this.j >= 10) {
|
|
x.a("java crash handler over %d, no need set.", 10);
|
|
return;
|
|
}
|
|
this.g = true;
|
|
Thread.UncaughtExceptionHandler defaultUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
|
|
if (defaultUncaughtExceptionHandler != null) {
|
|
if (getClass().getName().equals(defaultUncaughtExceptionHandler.getClass().getName())) {
|
|
return;
|
|
}
|
|
if ("com.android.internal.os.RuntimeInit$UncaughtHandler".equals(defaultUncaughtExceptionHandler.getClass().getName())) {
|
|
x.a("backup system java handler: %s", defaultUncaughtExceptionHandler.toString());
|
|
this.f = defaultUncaughtExceptionHandler;
|
|
this.e = defaultUncaughtExceptionHandler;
|
|
} else {
|
|
x.a("backup java handler: %s", defaultUncaughtExceptionHandler.toString());
|
|
this.e = defaultUncaughtExceptionHandler;
|
|
}
|
|
}
|
|
Thread.setDefaultUncaughtExceptionHandler(this);
|
|
this.j++;
|
|
x.a("registered java monitor: %s", toString());
|
|
}
|
|
|
|
public final synchronized void b() {
|
|
this.g = false;
|
|
x.a("close java monitor!", new Object[0]);
|
|
if (Thread.getDefaultUncaughtExceptionHandler().getClass().getName().contains("bugly")) {
|
|
x.a("Java monitor to unregister: %s", toString());
|
|
Thread.setDefaultUncaughtExceptionHandler(this.e);
|
|
this.j--;
|
|
}
|
|
}
|
|
|
|
@Override // java.lang.Thread.UncaughtExceptionHandler
|
|
public final void uncaughtException(Thread thread, Throwable th) {
|
|
synchronized (i) {
|
|
a(thread, th, true, null, null);
|
|
}
|
|
}
|
|
|
|
private CrashDetailBean b(Thread thread, Throwable th, boolean z, String str, byte[] bArr) {
|
|
String a;
|
|
boolean z2 = false;
|
|
if (th == null) {
|
|
x.d("We can do nothing with a null throwable.", new Object[0]);
|
|
return null;
|
|
}
|
|
boolean k = c.a().k();
|
|
String str2 = (k && z) ? " This Crash Caused By ANR , PLS To Fix ANR , This Trace May Be Not Useful![Bugly]" : "";
|
|
if (k && z) {
|
|
x.e("This Crash Caused By ANR , PLS To Fix ANR , This Trace May Be Not Useful!", new Object[0]);
|
|
}
|
|
CrashDetailBean crashDetailBean = new CrashDetailBean();
|
|
crashDetailBean.C = com.tencent.bugly.crashreport.common.info.b.k();
|
|
crashDetailBean.D = com.tencent.bugly.crashreport.common.info.b.i();
|
|
crashDetailBean.E = com.tencent.bugly.crashreport.common.info.b.m();
|
|
crashDetailBean.F = this.d.p();
|
|
crashDetailBean.G = this.d.o();
|
|
crashDetailBean.H = this.d.q();
|
|
crashDetailBean.w = z.a(this.a, c.e, (String) null);
|
|
crashDetailBean.y = y.a();
|
|
Object[] objArr = new Object[1];
|
|
byte[] bArr2 = crashDetailBean.y;
|
|
objArr[0] = Integer.valueOf(bArr2 == null ? 0 : bArr2.length);
|
|
x.a("user log size:%d", objArr);
|
|
crashDetailBean.b = z ? 0 : 2;
|
|
crashDetailBean.e = this.d.h();
|
|
com.tencent.bugly.crashreport.common.info.a aVar = this.d;
|
|
crashDetailBean.f = aVar.j;
|
|
crashDetailBean.g = aVar.w();
|
|
crashDetailBean.m = this.d.g();
|
|
String name = th.getClass().getName();
|
|
String b = b(th, 1000);
|
|
if (b == null) {
|
|
b = "";
|
|
}
|
|
Object[] objArr2 = new Object[2];
|
|
objArr2[0] = Integer.valueOf(th.getStackTrace().length);
|
|
objArr2[1] = Boolean.valueOf(th.getCause() != null);
|
|
x.e("stack frame :%d, has cause %b", objArr2);
|
|
String stackTraceElement = th.getStackTrace().length > 0 ? th.getStackTrace()[0].toString() : "";
|
|
Throwable th2 = th;
|
|
while (th2 != null && th2.getCause() != null) {
|
|
th2 = th2.getCause();
|
|
}
|
|
if (th2 != null && th2 != th) {
|
|
crashDetailBean.n = th2.getClass().getName();
|
|
crashDetailBean.o = b(th2, 1000);
|
|
if (crashDetailBean.o == null) {
|
|
crashDetailBean.o = "";
|
|
}
|
|
if (th2.getStackTrace().length > 0) {
|
|
crashDetailBean.p = th2.getStackTrace()[0].toString();
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append(name);
|
|
sb.append(":");
|
|
sb.append(b);
|
|
sb.append("\n");
|
|
sb.append(stackTraceElement);
|
|
sb.append("\n......");
|
|
sb.append("\nCaused by:\n");
|
|
sb.append(crashDetailBean.n);
|
|
sb.append(":");
|
|
sb.append(crashDetailBean.o);
|
|
sb.append("\n");
|
|
a = a(th2, c.f);
|
|
sb.append(a);
|
|
crashDetailBean.q = sb.toString();
|
|
} else {
|
|
crashDetailBean.n = name;
|
|
crashDetailBean.o = b + str2;
|
|
if (crashDetailBean.o == null) {
|
|
crashDetailBean.o = "";
|
|
}
|
|
crashDetailBean.p = stackTraceElement;
|
|
a = a(th, c.f);
|
|
crashDetailBean.q = a;
|
|
}
|
|
crashDetailBean.r = System.currentTimeMillis();
|
|
crashDetailBean.u = z.b(crashDetailBean.q.getBytes());
|
|
try {
|
|
crashDetailBean.z = z.a(c.f, false);
|
|
crashDetailBean.A = this.d.d;
|
|
crashDetailBean.B = thread.getName() + "(" + thread.getId() + ")";
|
|
crashDetailBean.z.put(crashDetailBean.B, a);
|
|
crashDetailBean.I = this.d.y();
|
|
crashDetailBean.h = this.d.v();
|
|
crashDetailBean.i = this.d.J();
|
|
crashDetailBean.M = this.d.a;
|
|
crashDetailBean.N = this.d.a();
|
|
crashDetailBean.P = this.d.H();
|
|
crashDetailBean.Q = this.d.I();
|
|
crashDetailBean.R = this.d.B();
|
|
crashDetailBean.S = this.d.G();
|
|
} catch (Throwable th3) {
|
|
x.e("handle crash error %s", th3.toString());
|
|
}
|
|
if (z) {
|
|
this.b.c(crashDetailBean);
|
|
} else {
|
|
boolean z3 = str != null && str.length() > 0;
|
|
if (bArr != null && bArr.length > 0) {
|
|
z2 = true;
|
|
}
|
|
if (z3) {
|
|
crashDetailBean.O = new HashMap(1);
|
|
crashDetailBean.O.put("UserData", str);
|
|
}
|
|
if (z2) {
|
|
crashDetailBean.T = bArr;
|
|
}
|
|
}
|
|
return crashDetailBean;
|
|
}
|
|
|
|
private static boolean a(Thread thread) {
|
|
synchronized (i) {
|
|
if (h != null && thread.getName().equals(h)) {
|
|
return true;
|
|
}
|
|
h = thread.getName();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public final void a(Thread thread, Throwable th, boolean z, String str, byte[] bArr) {
|
|
if (z) {
|
|
x.e("Java Crash Happen cause by %s(%d)", thread.getName(), Long.valueOf(thread.getId()));
|
|
if (a(thread)) {
|
|
x.a("this class has handled this exception", new Object[0]);
|
|
if (this.f != null) {
|
|
x.a("call system handler", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
} else {
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
}
|
|
}
|
|
} else {
|
|
x.e("Java Catch Happen", new Object[0]);
|
|
}
|
|
try {
|
|
if (!this.g) {
|
|
x.c("Java crash handler is disable. Just return.", new Object[0]);
|
|
if (z) {
|
|
Thread.UncaughtExceptionHandler uncaughtExceptionHandler = this.e;
|
|
if (uncaughtExceptionHandler != null && a(uncaughtExceptionHandler)) {
|
|
x.e("sys default last handle start!", new Object[0]);
|
|
this.e.uncaughtException(thread, th);
|
|
x.e("sys default last handle end!", new Object[0]);
|
|
return;
|
|
} else if (this.f != null) {
|
|
x.e("system handle start!", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
x.e("system handle end!", new Object[0]);
|
|
return;
|
|
} else {
|
|
x.e("crashreport last handle start!", new Object[0]);
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
x.e("crashreport last handle end!", new Object[0]);
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (!this.c.b()) {
|
|
x.d("no remote but still store!", new Object[0]);
|
|
}
|
|
if (!this.c.c().g && this.c.b()) {
|
|
x.e("crash report was closed by remote , will not upload to Bugly , print local for helpful!", new Object[0]);
|
|
b.a(z ? "JAVA_CRASH" : "JAVA_CATCH", z.a(), this.d.d, thread.getName(), z.a(th), null);
|
|
if (z) {
|
|
Thread.UncaughtExceptionHandler uncaughtExceptionHandler2 = this.e;
|
|
if (uncaughtExceptionHandler2 != null && a(uncaughtExceptionHandler2)) {
|
|
x.e("sys default last handle start!", new Object[0]);
|
|
this.e.uncaughtException(thread, th);
|
|
x.e("sys default last handle end!", new Object[0]);
|
|
return;
|
|
} else if (this.f != null) {
|
|
x.e("system handle start!", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
x.e("system handle end!", new Object[0]);
|
|
return;
|
|
} else {
|
|
x.e("crashreport last handle start!", new Object[0]);
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
x.e("crashreport last handle end!", new Object[0]);
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
CrashDetailBean b = b(thread, th, z, str, bArr);
|
|
if (b == null) {
|
|
x.e("pkg crash datas fail!", new Object[0]);
|
|
if (z) {
|
|
Thread.UncaughtExceptionHandler uncaughtExceptionHandler3 = this.e;
|
|
if (uncaughtExceptionHandler3 != null && a(uncaughtExceptionHandler3)) {
|
|
x.e("sys default last handle start!", new Object[0]);
|
|
this.e.uncaughtException(thread, th);
|
|
x.e("sys default last handle end!", new Object[0]);
|
|
return;
|
|
} else if (this.f != null) {
|
|
x.e("system handle start!", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
x.e("system handle end!", new Object[0]);
|
|
return;
|
|
} else {
|
|
x.e("crashreport last handle start!", new Object[0]);
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
x.e("crashreport last handle end!", new Object[0]);
|
|
return;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
b.a(z ? "JAVA_CRASH" : "JAVA_CATCH", z.a(), this.d.d, thread.getName(), z.a(th), b);
|
|
if (!this.b.a(b)) {
|
|
this.b.a(b, 3000L, z);
|
|
}
|
|
if (z) {
|
|
this.b.b(b);
|
|
}
|
|
if (z) {
|
|
Thread.UncaughtExceptionHandler uncaughtExceptionHandler4 = this.e;
|
|
if (uncaughtExceptionHandler4 != null && a(uncaughtExceptionHandler4)) {
|
|
x.e("sys default last handle start!", new Object[0]);
|
|
this.e.uncaughtException(thread, th);
|
|
x.e("sys default last handle end!", new Object[0]);
|
|
} else if (this.f != null) {
|
|
x.e("system handle start!", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
x.e("system handle end!", new Object[0]);
|
|
} else {
|
|
x.e("crashreport last handle start!", new Object[0]);
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
x.e("crashreport last handle end!", new Object[0]);
|
|
}
|
|
}
|
|
} catch (Throwable th2) {
|
|
try {
|
|
if (!x.a(th2)) {
|
|
th2.printStackTrace();
|
|
}
|
|
if (z) {
|
|
Thread.UncaughtExceptionHandler uncaughtExceptionHandler5 = this.e;
|
|
if (uncaughtExceptionHandler5 != null && a(uncaughtExceptionHandler5)) {
|
|
x.e("sys default last handle start!", new Object[0]);
|
|
this.e.uncaughtException(thread, th);
|
|
x.e("sys default last handle end!", new Object[0]);
|
|
} else if (this.f != null) {
|
|
x.e("system handle start!", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
x.e("system handle end!", new Object[0]);
|
|
} else {
|
|
x.e("crashreport last handle start!", new Object[0]);
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
x.e("crashreport last handle end!", new Object[0]);
|
|
}
|
|
}
|
|
} catch (Throwable th3) {
|
|
if (z) {
|
|
Thread.UncaughtExceptionHandler uncaughtExceptionHandler6 = this.e;
|
|
if (uncaughtExceptionHandler6 != null && a(uncaughtExceptionHandler6)) {
|
|
x.e("sys default last handle start!", new Object[0]);
|
|
this.e.uncaughtException(thread, th);
|
|
x.e("sys default last handle end!", new Object[0]);
|
|
} else if (this.f != null) {
|
|
x.e("system handle start!", new Object[0]);
|
|
this.f.uncaughtException(thread, th);
|
|
x.e("system handle end!", new Object[0]);
|
|
} else {
|
|
x.e("crashreport last handle start!", new Object[0]);
|
|
x.e("current process die", new Object[0]);
|
|
Process.killProcess(Process.myPid());
|
|
System.exit(1);
|
|
x.e("crashreport last handle end!", new Object[0]);
|
|
}
|
|
}
|
|
throw th3;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static String b(Throwable th, int i2) {
|
|
if (th.getMessage() == null) {
|
|
return "";
|
|
}
|
|
if (th.getMessage().length() <= 1000) {
|
|
return th.getMessage();
|
|
}
|
|
return th.getMessage().substring(0, 1000) + "\n[Message over limit size:1000, has been cutted!]";
|
|
}
|
|
|
|
private static boolean a(Thread.UncaughtExceptionHandler uncaughtExceptionHandler) {
|
|
if (uncaughtExceptionHandler == null) {
|
|
return true;
|
|
}
|
|
String name = uncaughtExceptionHandler.getClass().getName();
|
|
for (StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
|
|
String className = stackTraceElement.getClassName();
|
|
String methodName = stackTraceElement.getMethodName();
|
|
if (name.equals(className) && "uncaughtException".equals(methodName)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public final synchronized void a(StrategyBean strategyBean) {
|
|
if (strategyBean != null) {
|
|
if (strategyBean.g != this.g) {
|
|
x.a("java changed to %b", Boolean.valueOf(strategyBean.g));
|
|
if (strategyBean.g) {
|
|
a();
|
|
return;
|
|
}
|
|
b();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static String a(Throwable th, int i2) {
|
|
if (th == null) {
|
|
return null;
|
|
}
|
|
StringBuilder sb = new StringBuilder();
|
|
try {
|
|
if (th.getStackTrace() != null) {
|
|
for (StackTraceElement stackTraceElement : th.getStackTrace()) {
|
|
if (i2 > 0 && sb.length() >= i2) {
|
|
sb.append("\n[Stack over limit size :" + i2 + " , has been cutted !]");
|
|
return sb.toString();
|
|
}
|
|
sb.append(stackTraceElement.toString());
|
|
sb.append("\n");
|
|
}
|
|
}
|
|
} catch (Throwable th2) {
|
|
x.e("gen stack error %s", th2.toString());
|
|
}
|
|
return sb.toString();
|
|
}
|
|
}
|