Record Java exceptions to app home directory

This commit is contained in:
Aaron Culliney 2015-06-06 12:23:14 -07:00
parent 3108e035ed
commit 2562c17d73
2 changed files with 82 additions and 1 deletions

View File

@ -19,6 +19,7 @@ import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
@ -60,6 +61,7 @@ public class Apple2Activity extends Activity {
private native void nativeGraphicsChanged(int width, int height);
private native void nativeOnKeyDown(int keyCode, int metaState);
private native void nativeOnKeyUp(int keyCode, int metaState);
private native void nativeOnUncaughtException(String home, String trace);
public native void nativeOnResume(boolean isSystemResume);
public native void nativeOnPause();
@ -146,6 +148,49 @@ public class Apple2Activity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Immediately set up exception handler ...
final String homeDir = "/data/data/"+this.getPackageName();
final Thread.UncaughtExceptionHandler defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable t) {
try {
StackTraceElement[] stackTraceElements = t.getStackTrace();
StringBuffer traceBuffer = new StringBuffer();
// prepend information about this device
traceBuffer.append(Build.BRAND);
traceBuffer.append("\n");
traceBuffer.append(Build.MODEL);
traceBuffer.append("\n");
traceBuffer.append(Build.MANUFACTURER);
traceBuffer.append("\n");
traceBuffer.append(Build.DEVICE);
traceBuffer.append("\n");
// now append the actual stack trace
traceBuffer.append(t.getClass().getName());
traceBuffer.append("\n");
final int maxTraceSize = 2048+1024+512; // probably should keep this less than a standard Linux PAGE_SIZE
for (StackTraceElement elt : stackTraceElements) {
traceBuffer.append(elt.toString());
traceBuffer.append("\n");
if (traceBuffer.length() >= maxTraceSize) {
break;
}
}
traceBuffer.append("\n");
nativeOnUncaughtException(homeDir, traceBuffer.toString());
} catch (Throwable terminator2) {
// Yo dawg, I hear you like exceptions in your exception handler! ...
}
defaultExceptionHandler.uncaughtException(thread, t);
}
});
Log.e(TAG, "onCreate()");
mDataDir = firstTimeInitialization();

View File

@ -192,6 +192,42 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnQuit(JNIEnv *env, jobject
}
}
#define _JAVA_CRASH_NAME "/jcrash.txt"
#define _HALF_PAGE_SIZE (PAGE_SIZE>>1)
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnUncaughtException(JNIEnv *env, jobject obj, jstring jhome, jstring jstr) {
RELEASE_ERRLOG("Uncaught Java Exception ...");
// Write to /data/data/org.deadc0de.apple2ix.demo/jcrash.txt
const char *home = (*env)->GetStringUTFChars(env, jhome, NULL);
char *q = (char *)home;
char buf[_HALF_PAGE_SIZE] = { 0 };
const char *p0 = &buf[0];
char *p = (char *)p0;
while (*q && (p-p0 < _HALF_PAGE_SIZE-1)) {
*p++ = *q++;
}
(*env)->ReleaseStringUTFChars(env, jhome, home);
q = &_JAVA_CRASH_NAME[0];
while (*q && (p-p0 < _HALF_PAGE_SIZE-1)) {
*p++ = *q++;
}
int fd = TEMP_FAILURE_RETRY(open(buf, (O_CREAT|O_APPEND|O_WRONLY), (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)));
if (fd == -1) {
RELEASE_ERRLOG("OOPS, could not create/write to java crash file");
return;
}
const char *str = (*env)->GetStringUTFChars(env, jstr, NULL);
jsize len = (*env)->GetStringUTFLength(env, jstr);
TEMP_FAILURE_RETRY(write(fd, str, len));
(*env)->ReleaseStringUTFChars(env, jstr, str);
TEMP_FAILURE_RETRY(fsync(fd));
TEMP_FAILURE_RETRY(close(fd));
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyDown(JNIEnv *env, jobject obj, jint keyCode, jint metaState) {
#if !TESTING
android_keycode_to_emulator(keyCode, metaState, true);
@ -249,7 +285,7 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeSetColor(JNIEnv *env, jobje
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeChooseDisk(JNIEnv *env, jobject obj, jstring jPath, jboolean driveA, jboolean readOnly) {
const char *path = (*env)->GetStringUTFChars(env, jPath, 0);
const char *path = (*env)->GetStringUTFChars(env, jPath, NULL);
int drive = driveA ? 0 : 1;
int ro = readOnly ? 1 : 0;