|
|
545c29 |
# HG changeset patch
|
|
|
545c29 |
# User stuefe
|
|
|
545c29 |
# Date 1497865921 -7200
|
|
|
545c29 |
# Mon Jun 19 11:52:01 2017 +0200
|
|
|
545c29 |
# Node ID ca0c7b2783e0102468218589a062e7ac4736aae2
|
|
|
545c29 |
# Parent 148a7d6c463ad1726bad8a9e8d5df191314d704b
|
|
|
545c29 |
8181419, PR3413, RH1463144: Race in jdwp invoker handling may lead to crashes or invalid results
|
|
|
545c29 |
Reviewed-by: sspitsyn, sgehwolf, clanger
|
|
|
545c29 |
|
|
|
545c29 |
diff --git a/src/share/back/invoker.c b/src/share/back/invoker.c
|
|
|
545c29 |
--- openjdk/jdk/src/share/back/invoker.c
|
|
|
545c29 |
+++ openjdk/jdk/src/share/back/invoker.c
|
|
|
545c29 |
@@ -212,30 +212,6 @@
|
|
|
545c29 |
}
|
|
|
545c29 |
|
|
|
545c29 |
/*
|
|
|
545c29 |
- * Delete saved global references - if any - for:
|
|
|
545c29 |
- * - a potentially thrown Exception
|
|
|
545c29 |
- * - a returned refernce/array value
|
|
|
545c29 |
- * See invoker_doInvoke() and invoke* methods where global references
|
|
|
545c29 |
- * are being saved.
|
|
|
545c29 |
- */
|
|
|
545c29 |
-static void
|
|
|
545c29 |
-deletePotentiallySavedGlobalRefs(JNIEnv *env, InvokeRequest *request)
|
|
|
545c29 |
-{
|
|
|
545c29 |
- /* Delete potentially saved return value */
|
|
|
545c29 |
- if ((request->invokeType == INVOKE_CONSTRUCTOR) ||
|
|
|
545c29 |
- (returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT)) ||
|
|
|
545c29 |
- (returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY))) {
|
|
|
545c29 |
- if (request->returnValue.l != NULL) {
|
|
|
545c29 |
- tossGlobalRef(env, &(request->returnValue.l));
|
|
|
545c29 |
- }
|
|
|
545c29 |
- }
|
|
|
545c29 |
- /* Delete potentially saved exception */
|
|
|
545c29 |
- if (request->exception != NULL) {
|
|
|
545c29 |
- tossGlobalRef(env, &(request->exception));
|
|
|
545c29 |
- }
|
|
|
545c29 |
-}
|
|
|
545c29 |
-
|
|
|
545c29 |
-/*
|
|
|
545c29 |
* Delete global argument references from the request which got put there before a
|
|
|
545c29 |
* invoke request was carried out. See fillInvokeRequest().
|
|
|
545c29 |
*/
|
|
|
545c29 |
@@ -744,6 +720,7 @@
|
|
|
545c29 |
jint id;
|
|
|
545c29 |
InvokeRequest *request;
|
|
|
545c29 |
jboolean detached;
|
|
|
545c29 |
+ jboolean mustReleaseReturnValue = JNI_FALSE;
|
|
|
545c29 |
|
|
|
545c29 |
JDI_ASSERT(thread);
|
|
|
545c29 |
|
|
|
545c29 |
@@ -787,6 +764,13 @@
|
|
|
545c29 |
id = request->id;
|
|
|
545c29 |
exc = request->exception;
|
|
|
545c29 |
returnValue = request->returnValue;
|
|
|
545c29 |
+
|
|
|
545c29 |
+ /* Release return value and exception references, but delay the release
|
|
|
545c29 |
+ * until after the return packet was sent. */
|
|
|
545c29 |
+ mustReleaseReturnValue = request->invokeType == INVOKE_CONSTRUCTOR ||
|
|
|
545c29 |
+ returnTypeTag(request->methodSignature) == JDWP_TAG(OBJECT) ||
|
|
|
545c29 |
+ returnTypeTag(request->methodSignature) == JDWP_TAG(ARRAY);
|
|
|
545c29 |
+
|
|
|
545c29 |
}
|
|
|
545c29 |
|
|
|
545c29 |
/*
|
|
|
545c29 |
@@ -801,6 +785,12 @@
|
|
|
545c29 |
*/
|
|
|
545c29 |
deleteGlobalArgumentRefs(env, request);
|
|
|
545c29 |
|
|
|
545c29 |
+ /* From now on, do not access the request structure anymore
|
|
|
545c29 |
+ * for this request id, because once we give up the invokerLock it may
|
|
|
545c29 |
+ * be immediately reused by a new invoke request.
|
|
|
545c29 |
+ */
|
|
|
545c29 |
+ request = NULL;
|
|
|
545c29 |
+
|
|
|
545c29 |
/*
|
|
|
545c29 |
* Give up the lock before I/O operation
|
|
|
545c29 |
*/
|
|
|
545c29 |
@@ -821,7 +811,12 @@
|
|
|
545c29 |
*/
|
|
|
545c29 |
eventHandler_lock(); // for proper lock order
|
|
|
545c29 |
debugMonitorEnter(invokerLock);
|
|
|
545c29 |
- deletePotentiallySavedGlobalRefs(env, request);
|
|
|
545c29 |
+ if (mustReleaseReturnValue && returnValue.l != NULL) {
|
|
|
545c29 |
+ tossGlobalRef(env, &returnValue.l);
|
|
|
545c29 |
+ }
|
|
|
545c29 |
+ if (exc != NULL) {
|
|
|
545c29 |
+ tossGlobalRef(env, &exc);
|
|
|
545c29 |
+ }
|
|
|
545c29 |
debugMonitorExit(invokerLock);
|
|
|
545c29 |
eventHandler_unlock();
|
|
|
545c29 |
}
|