From 7ace05b06de32ad1046ded485a2202ec35250fd6 Mon Sep 17 00:00:00 2001 From: Greg Hazel Date: Fri, 25 May 2018 02:04:21 -0700 Subject: [PATCH] use libunwind data, and call bugsnag_add_breadcrumb directly --- android.c | 28 ++---------------- bugsnag/bugsnag_ndk.c | 63 ++++++++++++++++++++++------------------ bugsnag/bugsnag_ndk.h | 1 + bugsnag/bugsnag_unwind.h | 1 + 4 files changed, 39 insertions(+), 54 deletions(-) diff --git a/android.c b/android.c index b9a5cf8e..f7d1bb25 100644 --- a/android.c +++ b/android.c @@ -194,31 +194,9 @@ void bugsnag_client_setup(JNIEnv* env) void bugsnag_leave_breadcrumb_log(const char *buf) { - JNIEnv *env; - if ((*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) { - return; - } - - (*env)->PushLocalFrame(env, 16); - - IMPORT(com/bugsnag/android, BreadcrumbType); - jfieldID fType = (*env)->GetStaticFieldID(env, cBreadcrumbType , "LOG", "Lcom/bugsnag/android/BreadcrumbType;"); - jobject jType = (*env)->GetStaticObjectField(env, cBreadcrumbType, fType); - jclass cClient = (*env)->GetObjectClass(env, bugsnagClient); - - IMPORT(java/util, HashMap); - jmethodID hashMapInit = (*env)->GetMethodID(env, cHashMap, "", "()V"); - jobject jMeta = (*env)->NewObject(env, cHashMap, hashMapInit); - jmethodID mPut = (*env)->GetMethodID(env, cHashMap, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); - (*env)->CallObjectMethod(env, jMeta, mPut, JSTR("stdout"), JSTR(buf)); - - CALL_VOID(cClient, bugsnagClient, leaveBreadcrumb, Ljava/lang/String;Lcom/bugsnag/android/BreadcrumbType;Ljava/util/Map;, - JSTR("newnode"), jType, jMeta); - - // XXX: compat -- old Java code doesn't have com.clostra.newnode.NewNode.BugsnagObserver - Java_com_bugsnag_android_ndk_BugsnagObserver_populateBreadcumbDetails(env, NULL); - - (*env)->PopLocalFrame(env, NULL); + bsg_breadcrumb *crumb = bugsnag_breadcrumb_init("newnode", BSG_CRUMB_LOG); + bugsnag_breadcrumb_add_metadata(crumb, "stdout", (char*)buf); + bugsnag_add_breadcrumb(crumb); } JNIEXPORT void JNICALL Java_com_clostra_newnode_NewNode_setCacheDir(JNIEnv* env, jobject thiz, jstring cacheDir) diff --git a/bugsnag/bugsnag_ndk.c b/bugsnag/bugsnag_ndk.c index 27e7a8cf..ba3e4ba9 100644 --- a/bugsnag/bugsnag_ndk.c +++ b/bugsnag/bugsnag_ndk.c @@ -350,41 +350,41 @@ static void bugsnag_signal_handler(int code, struct siginfo *si, void *sc) { unwind_struct_frame *unwind_frame = &g_native_code->frames[i]; - Dl_info info; - if (dladdr(unwind_frame->frame_pointer, &info) != 0) { + bsg_stackframe frame = { + .method = unwind_frame->method, + .file = unwind_frame->file, + .line_number = (int) unwind_frame->frame_pointer, + .frame_address = (uintptr_t) unwind_frame->frame_pointer + }; + + if (strlen(unwind_frame->file) == 0) { + Dl_info info; + if (dladdr(unwind_frame->frame_pointer, &info) != 0) { + if (info.dli_fname != NULL) { + frame.file = info.dli_fname; + } - bsg_stackframe frame; - - if (info.dli_fname != NULL) { - frame.file = info.dli_fname; - } - - // use the method from unwind if there is one - if (strlen(unwind_frame->method) > 1) { - frame.method = unwind_frame->method; - } else { frame.method = info.dli_sname; - } - // Attempt to calculate the line numbers TODO: this gets the position in the file in bytes - frame.load_address = (uintptr_t) info.dli_fbase; - frame.symbol_address = (uintptr_t) info.dli_saddr; - frame.frame_address = (uintptr_t) unwind_frame->frame_pointer; - - uintptr_t file_offset = - (uintptr_t) unwind_frame->frame_pointer - (uintptr_t) info.dli_fbase; - frame.line_number = (int) file_offset; - - // Check if this is a system file, or handler function - if (is_system_file(frame.file) - || is_system_method(frame.method)) { - frame.in_project = 0; - } else { - frame.in_project = 1; + // Attempt to calculate the line numbers TODO: this gets the position in the file in bytes + frame.load_address = (uintptr_t) info.dli_fbase; + frame.symbol_address = (uintptr_t) info.dli_saddr; + + uintptr_t file_offset = + (uintptr_t) unwind_frame->frame_pointer - (uintptr_t) info.dli_fbase; + frame.line_number = (int) file_offset; } + } - bugsnag_exception_add_frame(exception, frame); + // Check if this is a system file, or handler function + if (is_system_file(frame.file) + || is_system_method(frame.method)) { + frame.in_project = 0; + } else { + frame.in_project = 1; } + + bugsnag_exception_add_frame(exception, frame); } } @@ -516,6 +516,11 @@ void bugsnag_set_user(char *id, char *email, char *name) { bugsnag_set_user_env(bugsnagGlobalEnv, id, email, name); } +void bugsnag_add_breadcrumb(bsg_breadcrumb* crumb) +{ + bugsnag_event_add_breadcrumb(g_bugsnag_report->event, crumb); +} + void bugsnag_leave_breadcrumb_env(JNIEnv *env, char *name, bsg_breadcrumb_t type) { time_t rawtime; diff --git a/bugsnag/bugsnag_ndk.h b/bugsnag/bugsnag_ndk.h index 306b55be..8b8d01ef 100644 --- a/bugsnag/bugsnag_ndk.h +++ b/bugsnag/bugsnag_ndk.h @@ -64,6 +64,7 @@ void bugsnag_set_user_env(JNIEnv *env, char* id, char* email, char* name); */ void bugsnag_leave_breadcrumb(char *name, bsg_breadcrumb_t type); void bugsnag_leave_breadcrumb_env(JNIEnv *env, char *name, bsg_breadcrumb_t type); +void bugsnag_add_breadcrumb(bsg_breadcrumb *crumb); #ifdef __cplusplus } diff --git a/bugsnag/bugsnag_unwind.h b/bugsnag/bugsnag_unwind.h index 3ddfcd15..92bfd17a 100644 --- a/bugsnag/bugsnag_unwind.h +++ b/bugsnag/bugsnag_unwind.h @@ -19,6 +19,7 @@ /* Structure to store unwound frame */ typedef struct unwind_struct_frame { void *frame_pointer; + char file[1024]; char method[1024]; } unwind_struct_frame;