summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: ca734bb)
raw | patch | inline | side by side (parent: ca734bb)
author | Sebastian Harl <sh@tokkee.org> | |
Sun, 23 Nov 2014 13:15:04 +0000 (14:15 +0100) | ||
committer | Sebastian Harl <sh@tokkee.org> | |
Sun, 23 Nov 2014 13:15:04 +0000 (14:15 +0100) |
Upstream fix for locking up the Java plugin by not properly detaching from the
JVM in error conditions. Thanks to Marc Fournier for reporting this.
Closes: #770690
JVM in error conditions. Thanks to Marc Fournier for reporting this.
Closes: #770690
debian/changelog | patch | blob | history | |
debian/patches/00list | patch | blob | history | |
debian/patches/bts770690_java_jni_thread_detach.dpatch | [new file with mode: 0755] | patch | blob |
diff --git a/debian/changelog b/debian/changelog
index 12045897af05d0b816c15ebe57ced28dd88713fc..950af5118f33e70261062c57132ad7ec0295b8b5 100644 (file)
--- a/debian/changelog
+++ b/debian/changelog
- Added bts770688_snmp_memleak: upstream fix for a memory leak in the
SNMP plugin; thanks to Marc Fournier for reporting this
(Closes: #770688).
+ - Added bts770690_java_jni_thread_detach: upstream fix for locking up the
+ Java plugin by not properly detaching from the JVM in error conditions;
+ thanks to Marc Fournier for reporting this (Closes: #770690).
-- Sebastian Harl <tokkee@debian.org> Sun, 23 Nov 2014 13:04:03 +0100
diff --git a/debian/patches/00list b/debian/patches/00list
index 51d49a0ec626c772a02d2a1243ffe5b56d5fb9f6..92316ee5157aa87bf8352773c909f7388ff893de 100644 (file)
--- a/debian/patches/00list
+++ b/debian/patches/00list
bts770683_curl_init.dpatch
bts750440_config_segfault.dpatch
bts770688_snmp_memleak.dpatch
+bts770690_java_jni_thread_detach.dpatch
diff --git a/debian/patches/bts770690_java_jni_thread_detach.dpatch b/debian/patches/bts770690_java_jni_thread_detach.dpatch
--- /dev/null
@@ -0,0 +1,205 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## bts770690_java_jni_thread_detach.dpatch by Florian Forster <octo@google.com>
+##
+## DP: java plugin: Make sure cjni_thread_detach() is called on all paths.
+## DP: Each call to cjni_thread_attach() much be accompanied by a call to
+## DP: cjni_thread_detach(). Some error handling cases were missing the call,
+## DP: potentially locking the plugin up.
+## DP:
+## DP: Also ensure that cjni_thread_detach() does not hide the status of other
+## DP: operations.
+## DP:
+## DP: Upstream commit:
+## DP: https://github.com/collectd/collectd/commit/513a5ca
+
+@DPATCH@
+
+diff a/src/java.c b/src/java.c
+--- a/src/java.c
++++ b/src/java.c
+@@ -2115,7 +2115,7 @@ static int cjni_thread_detach (void) /* {{{ */
+ cjni_env->jvm_env = NULL;
+
+ return (0);
+-} /* }}} JNIEnv *cjni_thread_attach */
++} /* }}} int cjni_thread_detach */
+
+ static int cjni_config_add_jvm_arg (oconfig_item_t *ci) /* {{{ */
+ {
+@@ -2468,7 +2468,6 @@ static int cjni_read (user_data_t *ud) /* {{{ */
+ {
+ JNIEnv *jvm_env;
+ cjni_callback_info_t *cbi;
+- int status;
+ int ret_status;
+
+ if (jvm == NULL)
+@@ -2492,13 +2491,7 @@ static int cjni_read (user_data_t *ud) /* {{{ */
+ ret_status = (*jvm_env)->CallIntMethod (jvm_env, cbi->object,
+ cbi->method);
+
+- status = cjni_thread_detach ();
+- if (status != 0)
+- {
+- ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
+- return (-1);
+- }
+-
++ cjni_thread_detach ();
+ return (ret_status);
+ } /* }}} int cjni_read */
+
+@@ -2509,7 +2502,6 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
+ JNIEnv *jvm_env;
+ cjni_callback_info_t *cbi;
+ jobject vl_java;
+- int status;
+ int ret_status;
+
+ if (jvm == NULL)
+@@ -2534,6 +2526,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
+ if (vl_java == NULL)
+ {
+ ERROR ("java plugin: cjni_write: ctoj_value_list failed.");
++ cjni_thread_detach ();
+ return (-1);
+ }
+
+@@ -2542,13 +2535,7 @@ static int cjni_write (const data_set_t *ds, const value_list_t *vl, /* {{{ */
+
+ (*jvm_env)->DeleteLocalRef (jvm_env, vl_java);
+
+- status = cjni_thread_detach ();
+- if (status != 0)
+- {
+- ERROR ("java plugin: cjni_write: cjni_thread_detach failed.");
+- return (-1);
+- }
+-
++ cjni_thread_detach ();
+ return (ret_status);
+ } /* }}} int cjni_write */
+
+@@ -2560,7 +2547,6 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
+ cjni_callback_info_t *cbi;
+ jobject o_timeout;
+ jobject o_identifier;
+- int status;
+ int ret_status;
+
+ if (jvm == NULL)
+@@ -2587,6 +2573,7 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
+ {
+ ERROR ("java plugin: cjni_flush: Converting double "
+ "to Number object failed.");
++ cjni_thread_detach ();
+ return (-1);
+ }
+
+@@ -2598,6 +2585,7 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
+ {
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
+ ERROR ("java plugin: cjni_flush: NewStringUTF failed.");
++ cjni_thread_detach ();
+ return (-1);
+ }
+ }
+@@ -2608,13 +2596,7 @@ static int cjni_flush (cdtime_t timeout, const char *identifier, /* {{{ */
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_identifier);
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_timeout);
+
+- status = cjni_thread_detach ();
+- if (status != 0)
+- {
+- ERROR ("java plugin: cjni_flush: cjni_thread_detach failed.");
+- return (-1);
+- }
+-
++ cjni_thread_detach ();
+ return (ret_status);
+ } /* }}} int cjni_flush */
+
+@@ -2640,7 +2622,10 @@ static void cjni_log (int severity, const char *message, /* {{{ */
+
+ o_message = (*jvm_env)->NewStringUTF (jvm_env, message);
+ if (o_message == NULL)
++ {
++ cjni_thread_detach ();
+ return;
++ }
+
+ (*jvm_env)->CallVoidMethod (jvm_env,
+ cbi->object, cbi->method, (jint) severity, o_message);
+@@ -2658,7 +2643,6 @@ static int cjni_notification (const notification_t *n, /* {{{ */
+ JNIEnv *jvm_env;
+ cjni_callback_info_t *cbi;
+ jobject o_notification;
+- int status;
+ int ret_status;
+
+ if (jvm == NULL)
+@@ -2683,6 +2667,7 @@ static int cjni_notification (const notification_t *n, /* {{{ */
+ if (o_notification == NULL)
+ {
+ ERROR ("java plugin: cjni_notification: ctoj_notification failed.");
++ cjni_thread_detach ();
+ return (-1);
+ }
+
+@@ -2691,13 +2676,7 @@ static int cjni_notification (const notification_t *n, /* {{{ */
+
+ (*jvm_env)->DeleteLocalRef (jvm_env, o_notification);
+
+- status = cjni_thread_detach ();
+- if (status != 0)
+- {
+- ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
+- return (-1);
+- }
+-
++ cjni_thread_detach ();
+ return (ret_status);
+ } /* }}} int cjni_notification */
+
+@@ -2725,24 +2704,20 @@ static int cjni_match_target_create (const oconfig_item_t *ci, /* {{{ */
+ (*jvm_env)->DeleteLocalRef (jvm_env, cbi_ret->object); \
+ } \
+ free (cbi_ret); \
+- if (jvm_env != NULL) { \
+- if (o_ci != NULL) \
+- (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \
+- cjni_thread_detach (); \
+- } \
++ if (o_ci != NULL) \
++ (*jvm_env)->DeleteLocalRef (jvm_env, o_ci); \
++ cjni_thread_detach (); \
+ return (status)
+
+ if (jvm == NULL)
+ {
+ ERROR ("java plugin: cjni_read: jvm == NULL");
+- BAIL_OUT (-1);
++ return (-1);
+ }
+
+ jvm_env = cjni_thread_attach ();
+ if (jvm_env == NULL)
+- {
+- BAIL_OUT (-1);
+- }
++ return (-1);
+
+ /* Find out whether to create a match or a target. */
+ if (strcasecmp ("Match", ci->key) == 0)
+@@ -2936,10 +2911,7 @@ static int cjni_match_target_invoke (const data_set_t *ds, /* {{{ */
+ }
+ } /* if (cbi->type == CB_TYPE_TARGET) */
+
+- status = cjni_thread_detach ();
+- if (status != 0)
+- ERROR ("java plugin: cjni_read: cjni_thread_detach failed.");
+-
++ cjni_thread_detach ();
+ return (ret_status);
+ } /* }}} int cjni_match_target_invoke */
+