OpenJDK / portola / portola
changeset 7978:120267233d5e
6436034: Instance filter doesn't filter event if it occurs in native method
Summary: Use 'GetLocalInstance' JVMTI extension if it exists
Reviewed-by: coleenp, dcubed
author | kamg |
---|---|
date | Wed, 12 Jan 2011 11:47:35 -0500 |
parents | f273c0d04215 |
children | 0ae19fac0c55 |
files | jdk/src/share/back/debugInit.c jdk/src/share/back/eventFilter.c jdk/src/share/instrument/JPLISAgent.c jdk/src/share/javavm/export/jvmti.h jdk/test/com/sun/jdi/NativeInstanceFilter.java jdk/test/com/sun/jdi/NativeInstanceFilterTarg.java |
diffstat | 6 files changed, 285 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/jdk/src/share/back/debugInit.c Wed Jan 12 14:40:36 2011 +0000 +++ b/jdk/src/share/back/debugInit.c Wed Jan 12 11:47:35 2011 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2010, 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 @@ -133,27 +133,60 @@ return error; } +typedef struct { + int major; + int minor; +} version_type; + +typedef struct { + version_type runtime; + version_type compiletime; +} compatible_versions_type; + +/* + * List of explicitly compatible JVMTI versions, specified as + * { runtime version, compile-time version } pairs. -1 is a wildcard. + */ +static int nof_compatible_versions = 3; +static compatible_versions_type compatible_versions_list[] = { + /* + * FIXUP: Allow version 0 to be compatible with anything + * Special check for FCS of 1.0. + */ + { { 0, -1 }, { -1, -1 } }, + { { -1, -1 }, { 0, -1 } }, + /* + * 1.2 is runtime compatible with 1.1 -- just make sure to check the + * version before using any new 1.2 features + */ + { { 1, 1 }, { 1, 2 } } +}; + + /* Logic to determine JVMTI version compatibility */ static jboolean compatible_versions(jint major_runtime, jint minor_runtime, jint major_compiletime, jint minor_compiletime) { -#if 1 /* FIXUP: We allow version 0 to be compatible with anything */ - /* Special check for FCS of 1.0. */ - if ( major_runtime == 0 || major_compiletime == 0 ) { - return JNI_TRUE; + /* + * First check to see if versions are explicitly compatible via the + * list specified above. + */ + int i; + for (i = 0; i < nof_compatible_versions; ++i) { + version_type runtime = compatible_versions_list[i].runtime; + version_type comptime = compatible_versions_list[i].compiletime; + + if ((major_runtime == runtime.major || runtime.major == -1) && + (minor_runtime == runtime.minor || runtime.minor == -1) && + (major_compiletime == comptime.major || comptime.major == -1) && + (minor_compiletime == comptime.minor || comptime.minor == -1)) { + return JNI_TRUE; + } } -#endif - /* Runtime major version must match. */ - if ( major_runtime != major_compiletime ) { - return JNI_FALSE; - } - /* Runtime minor version must be >= the version compiled with. */ - if ( minor_runtime < minor_compiletime ) { - return JNI_FALSE; - } - /* Assumed compatible */ - return JNI_TRUE; + + return major_runtime == major_compiletime && + minor_runtime >= minor_compiletime; } /* OnLoad startup:
--- a/jdk/src/share/back/eventFilter.c Wed Jan 12 14:40:36 2011 +0000 +++ b/jdk/src/share/back/eventFilter.c Wed Jan 12 11:47:35 2011 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2010, 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 @@ -39,6 +39,7 @@ #include "stepControl.h" #include "threadControl.h" #include "SDE.h" +#include "jvmti.h" typedef struct ClassFilter { jclass clazz; @@ -275,6 +276,24 @@ } } +static jboolean isVersionGte12x() { + jint version; + jvmtiError err = + JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)(gdata->jvmti, &version); + + if (err == JVMTI_ERROR_NONE) { + jint major, minor; + + major = (version & JVMTI_VERSION_MASK_MAJOR) + >> JVMTI_VERSION_SHIFT_MAJOR; + minor = (version & JVMTI_VERSION_MASK_MINOR) + >> JVMTI_VERSION_SHIFT_MINOR; + return (major > 1 || major == 1 && minor >= 2); + } else { + return JNI_FALSE; + } +} + /* Return the object instance in which the event occurred */ /* Return NULL if static or if an error occurs */ static jobject @@ -286,6 +305,14 @@ jint modifiers = 0; jvmtiError error; + static jboolean got_version = JNI_FALSE; + static jboolean is_version_gte_12x = JNI_FALSE; + + if (!got_version) { + is_version_gte_12x = isVersionGte12x(); + got_version = JNI_TRUE; + } + switch (evinfo->ei) { case EI_SINGLE_STEP: case EI_BREAKPOINT: @@ -314,11 +341,18 @@ /* fail if error or static (0x8) */ if (error == JVMTI_ERROR_NONE && thread!=NULL && (modifiers & 0x8) == 0) { FrameNumber fnum = 0; - /* get slot zero object "this" */ - error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject) - (gdata->jvmti, thread, fnum, 0, &object); - if (error != JVMTI_ERROR_NONE) + if (is_version_gte_12x) { + /* Use new 1.2.x function, GetLocalInstance */ + error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalInstance) + (gdata->jvmti, thread, fnum, &object); + } else { + /* get slot zero object "this" */ + error = JVMTI_FUNC_PTR(gdata->jvmti,GetLocalObject) + (gdata->jvmti, thread, fnum, 0, &object); + } + if (error != JVMTI_ERROR_NONE) { object = NULL; + } } return object;
--- a/jdk/src/share/instrument/JPLISAgent.c Wed Jan 12 14:40:36 2011 +0000 +++ b/jdk/src/share/instrument/JPLISAgent.c Wed Jan 12 11:47:35 2011 -0500 @@ -209,7 +209,7 @@ *agent_ptr = NULL; jnierror = (*vm)->GetEnv( vm, (void **) &jvmtienv, - JVMTI_VERSION); + JVMTI_VERSION_1_1); if ( jnierror != JNI_OK ) { initerror = JPLIS_INIT_ERROR_CANNOT_CREATE_NATIVE_AGENT; } else { @@ -990,7 +990,7 @@ } jnierror = (*agent->mJVM)->GetEnv( agent->mJVM, (void **) &retransformerEnv, - JVMTI_VERSION); + JVMTI_VERSION_1_1); if ( jnierror != JNI_OK ) { return NULL; }
--- a/jdk/src/share/javavm/export/jvmti.h Wed Jan 12 14:40:36 2011 +0000 +++ b/jdk/src/share/javavm/export/jvmti.h Wed Jan 12 11:47:35 2011 -0500 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2010, 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 @@ -41,8 +41,9 @@ JVMTI_VERSION_1 = 0x30010000, JVMTI_VERSION_1_0 = 0x30010000, JVMTI_VERSION_1_1 = 0x30010100, - - JVMTI_VERSION = 0x30000000 + (1 * 0x10000) + (1 * 0x100) + 102 /* version: 1.1.102 */ + JVMTI_VERSION_1_2 = 0x30010200, + + JVMTI_VERSION = 0x30000000 + (1 * 0x10000) + (2 * 0x100) + 1 /* version: 1.2.1 */ }; JNIEXPORT jint JNICALL @@ -1774,6 +1775,12 @@ jobject object, jlong* size_ptr); + /* 155 : Get Local Instance */ + jvmtiError (JNICALL *GetLocalInstance) (jvmtiEnv* env, + jthread thread, + jint depth, + jobject* value_ptr); + } jvmtiInterface_1; struct _jvmtiEnv { @@ -2031,6 +2038,12 @@ return functions->GetLocalObject(this, thread, depth, slot, value_ptr); } + jvmtiError GetLocalInstance(jthread thread, + jint depth, + jobject* value_ptr) { + return functions->GetLocalInstance(this, thread, depth, value_ptr); + } + jvmtiError GetLocalInt(jthread thread, jint depth, jint slot, @@ -2518,3 +2531,4 @@ #endif /* __cplusplus */ #endif /* !_JAVA_JVMTI_H_ */ +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jdi/NativeInstanceFilter.java Wed Jan 12 11:47:35 2011 -0500 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2010, 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 + * @bug 6426034 + * @summary Instance filter doesn't filter event if it occurs in native method + * + * @author Keith McGuigan + * + * @library scaffold + * @run build JDIScaffold VMConnection + * @compile -XDignore.symbol.file NativeInstanceFilterTarg.java + * @run main/othervm NativeInstanceFilter + */ + +/* + * This test tests instance filters for events generated from a native method + */ + +import java.util.*; +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import com.sun.jdi.request.*; + +public class NativeInstanceFilter extends JDIScaffold { + + static int unfilteredEvents = 0; + + public static void main(String args[]) throws Exception { + new NativeInstanceFilter().startTests(); + } + + public NativeInstanceFilter() { + super(); + } + + static EventRequestManager requestManager = null; + static MethodExitRequest request = null; + + private void listen() { + TargetAdapter adapter = new TargetAdapter() { + EventSet set = null; + ObjectReference instance = null; + + public boolean eventSetReceived(EventSet set) { + this.set = set; + return false; + } + + public boolean methodExited(MethodExitEvent event) { + String name = event.method().name(); + if (instance == null && name.equals("latch")) { + // Grab the instance (return value) and set up as filter + System.out.println("Setting up instance filter"); + instance = (ObjectReference)event.returnValue(); + requestManager.deleteEventRequest(request); + request = requestManager.createMethodExitRequest(); + request.addInstanceFilter(instance); + request.enable(); + } else if (instance != null && name.equals("intern")) { + // If not for the filter, this will be called twice + System.out.println("method exit event (String.intern())"); + ++unfilteredEvents; + } + set.resume(); + return false; + } + }; + addListener(adapter); + } + + + protected void runTests() throws Exception { + String[] args = new String[2]; + args[0] = "-connect"; + args[1] = "com.sun.jdi.CommandLineLaunch:main=NativeInstanceFilterTarg"; + + connect(args); + waitForVMStart(); + + // VM has started, but hasn't started running the test program yet. + requestManager = vm().eventRequestManager(); + ReferenceType referenceType = + resumeToPrepareOf("NativeInstanceFilterTarg").referenceType(); + + request = requestManager.createMethodExitRequest(); + request.enable(); + + listen(); + + vm().resume(); + + waitForVMDeath(); + + if (unfilteredEvents != 1) { + throw new Exception( + "Failed: Event from native frame not filtered out."); + } + System.out.println("Passed: Event filtered out."); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/jdi/NativeInstanceFilterTarg.java Wed Jan 12 11:47:35 2011 -0500 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010, 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. + */ + +import sun.misc.Version; + +public class NativeInstanceFilterTarg { + + public static void main(String args[]) { + boolean runTest = jvmSupportsJVMTI_12x(); + String s1 = "abc"; + String s2 = "def"; + latch(s1); + s1.intern(); + if (runTest) { + s2.intern(); // this is the call that generates events that ought + // to be filtered out. + } else { + System.out.println("Neutering test since JVMTI 1.2 not supported"); + } + } + + // Used by debugger to get an instance to filter with + public static String latch(String s) { return s; } + + public static boolean jvmSupportsJVMTI_12x() { + // This fix requires the JVM to support JVMTI 1.2, which doesn't + // happen until HSX 20.0, build 05. + int major = Version.jvmMajorVersion(); + int minor = Version.jvmMinorVersion(); + int micro = Version.jvmMicroVersion(); + int build = Version.jvmBuildNumber(); + + return (major > 20 || major == 20 && + (minor > 0 || micro > 0 || build >= 5)); + } +}