JDK-6551457 : JVMTI: reference_info in HeapReferenceCallback is not NULL for "otherwise" reference_kind
  • Type: Bug
  • Component: hotspot
  • Sub-Component: jvmti
  • Affected Version: 6
  • Priority: P2
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2007-04-28
  • Updated: 2011-09-22
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6 JDK 7 Other
6u10Fixed 7Fixed hs11Fixed
Description
Filed By       : JCK team
JDK            : java full version "1.6.0-fcs"
JCK            : 6a-b11
Platform[s]    : all
switch/Mode    : default
JCK test owner : http://javaweb.sfbay/jcce/tcks/jck/docs/others/owners.jto
Failed tests:
  vm/jvmti/FollowReferences/fref001/fref00107/fref00107.html
  vm/jvmti/FollowReferences/fref001/fref00107/fref00107a.html

The JVM TI 1.1 specification for Heap Reference Callback at:
  http://javaweb.sfbay/java/re/jdk/6.0/latest/docs/platform/jvmti/jvmti.html#jvmtiHeapReferenceCallback
states as follows:
  ---Excerpt-from-spec---
  typedef jint (JNICALL *jvmtiHeapReferenceCallback)
      (jvmtiHeapReferenceKind reference_kind, 
       const jvmtiHeapReferenceInfo* reference_info, 
       jlong class_tag, 
       jlong referrer_class_tag, 
       jlong size, 
       jlong* tag_ptr, 
       jlong* referrer_tag_ptr, 
       jint length, 
       void* user_data);
  ...
  reference_info  const jvmtiHeapReferenceInfo*

  Details about the reference. Set when the reference_kind is JVMTI_HEAP_REFERENCE_FIELD,
  JVMTI_HEAP_REFERENCE_STATIC_FIELD, JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT, JVMTI_HEAP_REFERENCE_CONSTANT_POOL,
  JVMTI_HEAP_REFERENCE_STACK_LOCAL, or JVMTI_HEAP_REFERENCE_JNI_LOCAL. Otherwise NULL.
  ---End-of-excerpt---

However, reference_info is not NULL when reference_kind is not one of above constants,
(for example, when reference_kind is JVMTI_HEAP_REFERENCE_CLASS).

Please see attached .jtr file for detail and use the following script to reproduce the failures:
--- runTest.sh ---
echo `uname -a`

TESTEDJDK="/java/re/jdk/6.0/latest/binaries/solaris-sparc"
CC="/net/ipcsdist/export1/patches/nozomi_patch/dist/sparc-S2/bin/cc"
JCK="/java/re/jck/6a/qac/latest/binaries/JCK-runtime-6a/"
OUTPUTDIR=$HOME
TESTCLASS="javasoft.sqe.tests.vm.jvmti.fref001.fref00107.fref00107"
AGENTOPTS="-agentlib:jckjvmti=fref00107"
JDKOPTS="-showversion -Xfuture"
TESTARGS="-platform.jvmtiSupported true"

echo "Compiling libjckjvmt.so ..."
${CC} -G -KPIC -o ${OUTPUTDIR}/libjckjvmti.so -I${JCK} -I${JCK}src/share/lib/jvmti/include \
    -I${JCK}src/share/lib/jni/include -I${JCK}src/share/lib/jni/include/solaris \
    ${JCK}src/share/lib/jvmti/jckjvmti.c

export LD_LIBRARY_PATH=${OUTPUTDIR}:${LD_LIBRARY_PATH}

echo " "
RUNCMD="${TESTEDJDK}/bin/java ${AGENTOPTS} ${JDKOPTS} -classpath ${JCK}/classes ${TESTCLASS} ${TESTARGS}"
echo "${RUNCMD}"
$RUNCMD
--- runTest.sh ---

Test output:
==============
<yg153347@sqeel> ./runTest.sh 
SunOS sqeel 5.9 Generic_122300-02 sun4u sparc SUNW,Ultra-Enterprise
Compiling libjckjvmt.so ...
 
/java/re/jdk/6.0/latest/binaries/solaris-sparc/bin/java -agentlib:jckjvmti=fref00107 -showversion -Xfuture -classpath /java/re/jck/6a/qac/latest/binaries/JCK-runtime-6a//classes javasoft.sqe.tests.vm.jvmti.fref001.fref00107.fref00107 -platform.jvmtiSupported true
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Server VM (build 1.6.0-b105, mixed mode)

Checking can_tag_objects capability ... available
reference_info is unexpectedly NOT NULL for JVMTI_HEAP_REFERENCE_CLASS
HeapReferenceCallback was called 605 times
==============

Sources for JCK tests failed due to this issue are available at:
  http://javaweb.sfbay.sun.com/java/re/jck/6a/qac/latest/binaries/JCK-runtime-6a/tests/vm/jvmti/FollowReferences/fref001/fref00107/fref00107.html

Comments
SUGGESTED FIX This is a suggested fix below (except that maybe the REF_INFO_MASK needs to be defined in the jvmtiTagMap.hpp instead of jvmtiTagMap.cpp): diff -c xx jvmtiTagMap.cpp *** xx Tue Jun 26 21:01:38 2007 --- jvmtiTagMap.cpp Tue Jun 26 22:13:35 2007 *************** *** 2230,2235 **** --- 2230,2239 ---- return true; } + #define REF_INFO_MASK ( (1 << JVMTI_HEAP_REFERENCE_FIELD) | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \ + | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \ + | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL) ) + // invoke the object reference callback to report a reference inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind, oop referrer, *************** *** 2271,2279 **** // for arrays we need the length, otherwise -1 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); // invoke the callback int res = (*cb)(ref_kind, ! &reference_info, wrapper.klass_tag(), wrapper.referrer_klass_tag(), wrapper.obj_size(), --- 2275,2284 ---- // for arrays we need the length, otherwise -1 jint len = (jint)(obj->is_array() ? arrayOop(obj)->length() : -1); + // invoke the callback int res = (*cb)(ref_kind, ! (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL, wrapper.klass_tag(), wrapper.referrer_klass_tag(), wrapper.obj_size(), With the fix above the JCK test is passed: ss45998@tomsk sh run SunOS tomsk 5.11 snv_55 i86pc i386 i86pc MYDIR=/home/ss45998/bugs/2007/6551457-heap3-jck /net/tomsk.sfbay/export/home/ss45998/1.5/hs_eret7.latest/i386/jdk1.7.0/bin/javac -g -cp /home/ss45998/bugs/2007/6551457-heap3-jck/jck/classes -d /home/ss45998/bugs/2007/6551457-heap3-jck/jck/classes fref00107/fref00107.java /net/tomsk.sfbay/export/home/ss45998/1.5/hs_eret7.latest/i386/jdk1.7.0/bin/java -agentlib:jckjvmti=fref00107 -showversion -Xfuture -classpath /home/ss45998/bugs/2007/6551457-heap3-jck/jck/classes javasoft.sqe.tests.vm.jvmti.fref001.fref00107.fref00107 -platform.jvmtiSupported true java version "1.7.0-ea" Java(TM) SE Runtime Environment (build 1.7.0-ea-b12) Java HotSpot(TM) Client VM (build 1.7.0-internal-fastdebug, mixed mode) Checking can_tag_objects capability ... available HeapReferenceCallback was called 8221 times
27-06-2007

EVALUATION The reference_info parameter is not used for some reference kinds (such a JVMTI_HEAP_REFERENCE_CLASS). The spec says that it is passed as NULL for those cases but the implementation passes an address of a reference info that is not populated. It's a corner case that is unlikely to impact real agents.
28-04-2007