[
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)