mirror of
https://github.com/openjdk/jdk8u.git
synced 2025-12-10 10:44:16 -06:00
8212155: Race condition when posting dynamic_code_generated event leads to JVM crash
Reviewed-by: phh, shade Backport-of: 64ec8b3e5c8a8d44c92591710d73b833f13c1500
This commit is contained in:
parent
c0a36d8fbe
commit
942d6d0614
@ -1890,13 +1890,17 @@ void JvmtiExport::post_dynamic_code_generated_while_holding_locks(const char* na
|
||||
address code_begin, address code_end)
|
||||
{
|
||||
// register the stub with the current dynamic code event collector
|
||||
JvmtiThreadState* state = JvmtiThreadState::state_for(JavaThread::current());
|
||||
// state can only be NULL if the current thread is exiting which
|
||||
// should not happen since we're trying to post an event
|
||||
guarantee(state != NULL, "attempt to register stub via an exiting thread");
|
||||
JvmtiDynamicCodeEventCollector* collector = state->get_dynamic_code_event_collector();
|
||||
guarantee(collector != NULL, "attempt to register stub without event collector");
|
||||
collector->register_stub(name, code_begin, code_end);
|
||||
// Cannot take safepoint here so do not use state_for to get
|
||||
// jvmti thread state.
|
||||
// The collector and/or state might be NULL if JvmtiDynamicCodeEventCollector
|
||||
// has been initialized while JVMTI_EVENT_DYNAMIC_CODE_GENERATED was disabled.
|
||||
JvmtiThreadState* state = JavaThread::current()->jvmti_thread_state();
|
||||
if (state != NULL) {
|
||||
JvmtiDynamicCodeEventCollector *collector = state->get_dynamic_code_event_collector();
|
||||
if (collector != NULL) {
|
||||
collector->register_stub(name, code_begin, code_end);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Collect all the vm internally allocated objects which are visible to java world
|
||||
|
||||
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
public class DynamicCodeGenerated {
|
||||
static {
|
||||
System.loadLibrary("DynamicCodeGenerated");
|
||||
}
|
||||
public static native void changeEventNotificationMode();
|
||||
|
||||
public static void main(String[] args) {
|
||||
// Try to enable DynamicCodeGenerated event while it is posted
|
||||
// using JvmtiDynamicCodeEventCollector from VtableStubs::find_stub
|
||||
Thread t = new Thread(() -> {
|
||||
changeEventNotificationMode();
|
||||
});
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
|
||||
for (int i = 0; i < 2000; i++) {
|
||||
new Thread(() -> {
|
||||
String result = "string" + System.currentTimeMillis();
|
||||
|
||||
// Keep a reference to result
|
||||
if (result.hashCode() == System.currentTimeMillis()) {
|
||||
// Shouldn't happen
|
||||
return;
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
|
||||
# @test DynamicCodeGeneratedTest.sh
|
||||
# @bug 8212155
|
||||
# @summary Test concurrent enabling and posting of DynamicCodeGenerated events.
|
||||
# @run shell DynamicCodeGeneratedTest.sh
|
||||
|
||||
if [ "$TESTSRC" = "" ]
|
||||
then TESTSRC=.
|
||||
fi
|
||||
|
||||
if [ "$TESTJAVA" = "" ]
|
||||
then
|
||||
PARENT=$(dirname $(which java))
|
||||
TESTJAVA=$(dirname $PARENT)
|
||||
echo "TESTJAVA not set, selecting " $TESTJAVA
|
||||
echo "If this is incorrect, try setting the variable manually."
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=$(uname -s)
|
||||
case "$OS" in
|
||||
Linux )
|
||||
ARCHFLAG=
|
||||
$TESTJAVA/bin/java -version 2>&1 | grep '64-Bit' > /dev/null
|
||||
if [ $? -eq '0' ]
|
||||
then
|
||||
ARCH="amd64"
|
||||
else
|
||||
ARCH="i386"
|
||||
ARCHFLAG="-m32 -march=i386"
|
||||
fi
|
||||
;;
|
||||
* )
|
||||
echo "Test passed, unrecognized system."
|
||||
exit 0;
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "OS-ARCH is" linux-$ARCH
|
||||
$TESTJAVA/jre/bin/java -fullversion 2>&1
|
||||
|
||||
which gcc >/dev/null 2>&1
|
||||
if [ "$?" -ne '0' ]
|
||||
then
|
||||
echo "No C compiler found. Test passed."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
JAVA=$TESTJAVA/jre/bin/java
|
||||
JAVAC=$TESTJAVA/bin/javac
|
||||
JAVAH=$TESTJAVA/bin/javah
|
||||
|
||||
$JAVAC -d . $TESTSRC/DynamicCodeGenerated.java
|
||||
$JAVAH -jni -classpath . -d . DynamicCodeGenerated
|
||||
|
||||
gcc --shared $ARCHFLAG -fPIC -O -I$TESTJAVA/include -I$TESTJAVA/include/linux -I. -o libDynamicCodeGenerated.so $TESTSRC/libDynamicCodeGenerated.cpp
|
||||
|
||||
LD_LIBRARY_PATH=. $JAVA -classpath . -agentlib:DynamicCodeGenerated DynamicCodeGenerated
|
||||
|
||||
exit $?
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <jvmti.h>
|
||||
|
||||
static jvmtiEnv* jvmti = NULL;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT
|
||||
void JNICALL Java_DynamicCodeGenerated_changeEventNotificationMode(JNIEnv* jni, jclass cls) {
|
||||
while (true) {
|
||||
jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL);
|
||||
jvmti->SetEventNotificationMode(JVMTI_DISABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
void JNICALL DynamicCodeGenerated(jvmtiEnv* jvmti, const char* name, const void* address, jint length) {
|
||||
|
||||
}
|
||||
|
||||
jint Agent_OnLoad(JavaVM* vm, char* options, void* reserved) {
|
||||
vm->GetEnv((void**)&jvmti, JVMTI_VERSION_1_0);
|
||||
jvmtiEventCallbacks callbacks;
|
||||
memset(&callbacks, 0, sizeof(callbacks));
|
||||
callbacks.DynamicCodeGenerated = DynamicCodeGenerated;
|
||||
jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user