[ 
https://issues.apache.org/jira/browse/MESOS-2414?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14345593#comment-14345593
 ] 

Benjamin Mahler commented on MESOS-2414:
----------------------------------------

[~drexin] For Case 2 with the segfault, can you use {{ulimit -c}} to enable 
core dumps (as suggested in the Java output), and include {{thread apply all 
bt}} output from gdb?

For Case 1 with NoSuchFieldError, I can't reproduce locally by doing a missing 
field lookup:

{code}
diff --git a/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp 
b/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp
index 4f0dad7..51d9089 100644
--- a/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp
+++ b/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp
@@ -16,6 +16,8 @@
  * limitations under the License.
  */

+#include <glog/logging.h>
+
 #include <string>
 #include <map>
 #include <vector>
@@ -498,6 +500,10 @@ JNIEXPORT void JNICALL 
Java_org_apache_mesos_MesosSchedulerDriver_initialize
   jfieldID master = env->GetFieldID(clazz, "master", "Ljava/lang/String;");
   jobject jmaster = env->GetObjectField(thiz, master);

+  Result<jfieldID> missing = getFieldID(env, clazz, "missing", "Z");
+  CHECK(missing.isNone())
+    << missing.error();
+
   // NOTE: Older versions (< 0.22.0) of MesosSchedulerDriver.java
   // do not have the 'implicitAcknowledgements' field, so when None()
   // is returned we default to the old behavior: implicit
{code}

This runs fine for me (the None case is what is expected), I'm guessing this 
leads to the "Unexpected exception" for you. Here is a diff that will add some 
more debugging information, sorry it's so messy (it was copy pasted):

{code}
diff --git a/src/java/jni/convert.cpp b/src/java/jni/convert.cpp
index 9f99031..0853a73 100644
--- a/src/java/jni/convert.cpp
+++ b/src/java/jni/convert.cpp
@@ -18,6 +18,7 @@

 #include <jni.h>

+#include <iostream>
 #include <string>
 #include <assert.h>

@@ -512,6 +513,94 @@ jobject convert(JNIEnv* env, const Status& status)
 }


+void _append_exception_trace_messages(
+                        JNIEnv&      a_jni_env,
+                        string& a_error_msg,
+                        jthrowable   a_exception,
+                        jmethodID    a_mid_throwable_getCause,
+                        jmethodID    a_mid_throwable_getStackTrace,
+                        jmethodID    a_mid_throwable_toString,
+                        jmethodID    a_mid_frame_toString)
+{
+    // Get the array of StackTraceElements.
+    jobjectArray frames =
+        (jobjectArray) a_jni_env.CallObjectMethod(
+                                        a_exception,
+                                        a_mid_throwable_getStackTrace);
+    jsize frames_length = a_jni_env.GetArrayLength(frames);
+
+    // Add Throwable.toString() before descending
+    // stack trace messages.
+    if (0 != frames)
+    {
+        jstring msg_obj =
+            (jstring) a_jni_env.CallObjectMethod(a_exception,
+                                                 a_mid_throwable_toString);
+        const char* msg_str = a_jni_env.GetStringUTFChars(msg_obj, 0);
+
+        // If this is not the top-of-the-trace then
+        // this is a cause.
+        if (!a_error_msg.empty())
+        {
+            a_error_msg += "\nCaused by: ";
+            a_error_msg += msg_str;
+        }
+        else
+        {
+            a_error_msg = msg_str;
+        }
+
+        a_jni_env.ReleaseStringUTFChars(msg_obj, msg_str);
+        a_jni_env.DeleteLocalRef(msg_obj);
+    }
+
+    // Append stack trace messages if there are any.
+    if (frames_length > 0)
+    {
+        jsize i = 0;
+        for (i = 0; i < frames_length; i++)
+        {
+            // Get the string returned from the 'toString()'
+            // method of the next frame and append it to
+            // the error message.
+            jobject frame = a_jni_env.GetObjectArrayElement(frames, i);
+            jstring msg_obj =
+                (jstring) a_jni_env.CallObjectMethod(frame,
+                                                     a_mid_frame_toString);
+
+            const char* msg_str = a_jni_env.GetStringUTFChars(msg_obj, 0);
+
+            a_error_msg += "\n    ";
+            a_error_msg += msg_str;
+
+            a_jni_env.ReleaseStringUTFChars(msg_obj, msg_str);
+            a_jni_env.DeleteLocalRef(msg_obj);
+            a_jni_env.DeleteLocalRef(frame);
+        }
+    }
+
+    // If 'a_exception' has a cause then append the
+    // stack trace messages from the cause.
+    if (0 != frames)
+    {
+        jthrowable cause =
+            (jthrowable) a_jni_env.CallObjectMethod(
+                            a_exception,
+                            a_mid_throwable_getCause);
+        if (0 != cause)
+        {
+            _append_exception_trace_messages(a_jni_env,
+                                             a_error_msg,
+                                             cause,
+                                             a_mid_throwable_getCause,
+                                             a_mid_throwable_getStackTrace,
+                                             a_mid_throwable_toString,
+                                             a_mid_frame_toString);
+        }
+    }
+}
+
+
 // Helper to safely return the 'jfieldID' of the given 'name'
 // and 'signature'. If the field doesn't exist 'None' is
 // returned. If any other JVM Exception is encountered an 'Error'
@@ -535,6 +624,63 @@ Result<jfieldID> getFieldID(
   jthrowable jexception = env->ExceptionOccurred();
   if (jexception != NULL) {
     env->ExceptionClear(); // Clear the exception first before proceeding.
+
+    // Get the error message:
+    jclass throwable_class = env->FindClass("java/lang/Throwable");
+    jmethodID mid_throwable_getCause = env->GetMethodID(
+        throwable_class, "getCause", "()Ljava/lang/Throwable;");
+    jmethodID mid_throwable_getStackTrace = env->GetMethodID(
+        throwable_class, "getStackTrace", "()[Ljava/lang/StackTraceElement;");
+    jmethodID mid_throwable_toString = env->GetMethodID(
+        throwable_class, "toString", "()Ljava/lang/String;");
+    jclass frame_class = env->FindClass("java/lang/StackTraceElement");
+    jmethodID mid_frame_toString = env->GetMethodID(
+        frame_class, "toString", "()Ljava/lang/String;");
+
+    string error_msg;
+
+    _append_exception_trace_messages(*env,
+                                     error_msg,
+                                     jexception,
+                                     mid_throwable_getCause,
+                                     mid_throwable_getStackTrace,
+                                     mid_throwable_toString,
+                                     mid_frame_toString);
+
+    std::cerr << error_msg << std::endl;
+
+    jclass clazz = env->GetObjectClass(jexception);
+    jmethodID getClass = env->GetMethodID(clazz, "getClass", 
"()Ljava/lang/Class;");
+    jobject jexceptionClassObject = env->CallObjectMethod(jexception, 
getClass);
+    clazz = env->GetObjectClass(jexceptionClassObject);
+    jmethodID getName = env->GetMethodID(
+        clazz, "getName", "()Ljava/lang/String;");
+    jstring stringObject = (jstring)
+      env->CallObjectMethod(jexceptionClassObject, getName);
+    const char* exceptionName_ = env->GetStringUTFChars(stringObject, NULL);
+
+    string exceptionName(exceptionName_);
+
+    env->ReleaseStringUTFChars(stringObject, exceptionName_);
+
+    clazz = env->GetObjectClass(NO_SUCH_FIELD_ERROR);
+    getName = env->GetMethodID(
+        clazz, "getName", "()Ljava/lang/String;");
+    stringObject = (jstring)
+      env->CallObjectMethod(NO_SUCH_FIELD_ERROR, getName);
+    const char* noSuchFieldErrorName_ = env->GetStringUTFChars(stringObject, 
NULL);
+
+    string noSuchFieldErrorName(noSuchFieldErrorName_);
+
+    env->ReleaseStringUTFChars(stringObject, noSuchFieldErrorName_);
+
+    // Print the class name
+    std::cerr << exceptionName << " IsInstanceOf " << noSuchFieldErrorName << 
" : "
+              << (construct(env, env->IsInstanceOf(jexception, 
NO_SUCH_FIELD_ERROR)) == true
+                  ? "true" : "false")
+              << std::endl;
+
+
     if (!env->IsInstanceOf(jexception, NO_SUCH_FIELD_ERROR)) {
       // We are here if we got a different exception than
       // 'NoSuchFieldError'. Rethrow and bail.
diff --git a/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp 
b/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp
index 4f0dad7..51d9089 100644
--- a/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp
+++ b/src/java/jni/org_apache_mesos_MesosSchedulerDriver.cpp
@@ -16,6 +16,8 @@
  * limitations under the License.
  */

+#include <glog/logging.h>
+
 #include <string>
 #include <map>
 #include <vector>
@@ -498,6 +500,10 @@ JNIEXPORT void JNICALL 
Java_org_apache_mesos_MesosSchedulerDriver_initialize
   jfieldID master = env->GetFieldID(clazz, "master", "Ljava/lang/String;");
   jobject jmaster = env->GetObjectField(thiz, master);

+  Result<jfieldID> missing = getFieldID(env, clazz, "missing", "Z");
+  CHECK(missing.isNone())
+    << missing.error();
+
   // NOTE: Older versions (< 0.22.0) of MesosSchedulerDriver.java
   // do not have the 'implicitAcknowledgements' field, so when None()
   // is returned we default to the old behavior: implicit
{code}

For me this prints the following:

{noformat}
java.lang.NoSuchFieldError: missing
    org.apache.mesos.MesosSchedulerDriver.initialize(Native Method)
    org.apache.mesos.MesosSchedulerDriver.<init>(MesosSchedulerDriver.java:238)
    TestFramework.main(TestFramework.java:241)
java.lang.NoSuchFieldError IsInstanceOf java.lang.NoSuchFieldError : true
{noformat}

> Java bindings segfault during framework shutdown
> ------------------------------------------------
>
>                 Key: MESOS-2414
>                 URL: https://issues.apache.org/jira/browse/MESOS-2414
>             Project: Mesos
>          Issue Type: Bug
>            Reporter: Niklas Quarfot Nielsen
>            Assignee: Niklas Quarfot Nielsen
>
> {code}
> I0226 16:39:59.063369 626044928 sched.cpp:831] Stopping framework 
> '20150220-141149-16777343-5050-45194-0000'
> [2015-02-26 16:39:59,063] INFO Driver future completed. Executing optional 
> abdication command. (mesosphere.marathon.MarathonSchedulerService:191)
> [2015-02-26 16:39:59,065] INFO Setting framework ID to 
> 20150220-141149-16777343-5050-45194-0000 
> (mesosphere.marathon.MarathonSchedulerService:75)
> #
> # A fatal error has been detected by the Java Runtime Environment:
> #
> #  SIGSEGV (0xb) at pc=0x0000000106a266d0, pid=99408, tid=44291
> #
> # JRE version: Java(TM) SE Runtime Environment (8.0_25-b17) (build 
> 1.8.0_25-b17)
> # Java VM: Java HotSpot(TM) 64-Bit Server VM (25.25-b02 mixed mode bsd-amd64 
> compressed oops)
> # Problematic frame:
> # V  [libjvm.dylib+0x4266d0]  Klass::is_subtype_of(Klass*) const+0x4
> #
> # Failed to write core dump. Core dumps have been disabled. To enable core 
> dumping, try "ulimit -c unlimited" before starting Java again
> #
> # An error report file with more information is saved as:
> # /Users/corpsi/projects/marathon/hs_err_pid99408.log
> #
> # If you would like to submit a bug report, please visit:
> #   http://bugreport.sun.com/bugreport/crash.jsp
> #
> Abort trap: 6
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to