United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-7178846 IterateThroughHeap: heap_iteration_callback passes a negative size for big array
JDK-7178846 : IterateThroughHeap: heap_iteration_callback passes a negative size for big array

Details
Type:
Bug
Submit Date:
2012-06-21
Status:
Resolved
Updated Date:
2013-04-30
Project Name:
JDK
Resolved Date:
2012-07-03
Component:
hotspot
OS:
windows_7
Sub-Component:
jvmti
CPU:
x86
Priority:
P4
Resolution:
Fixed
Affected Versions:
7
Fixed Versions:
hs24 (b15)

Related Reports
Backport:
Backport:
Backport:

Sub Tasks

Description
FULL PRODUCT VERSION :


A DESCRIPTION OF THE PROBLEM :
If there is an array of size close to 2 GB, its size is reported as a negative value to the heap_iteration_callback in IterateThroughHeap

THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: Did not try

THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Did not try

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Compile a Java class NegativeArraySize (see source code) which creates a big char[] and calls a native method to trigger IterateThroughHeap

2. Compile a C++ agent as a 64-bit dll to get agent.dll

3. Run the test:

<path to 64-bit Java 7 or Java 6>/java  -Xmx4G -agentlib:agent -cp . NegativeArraySize

An object with negative size will be reported.


EXPECTED VERSUS ACTUAL BEHAVIOR :
Actual:

"negative size: array_length=1074790398"

Expected:

a negative size is never reported

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
===========================================
The Java class:
===========================================

public class NegativeArraySize {
  static native void iterateHeap();

  static char[] array = new char[1074790398]; // keep from GC

  public static void main(String[] args) {
    iterateHeap();
  }
}

===========================================
The C++ agent:
===========================================
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <jvmti.h>

static jvmtiEnv* ourJVMTI;

#define ZERO(X) memset(&X, 0, sizeof(X))

/* Check for JVMTI error */
void check_JVMTI_error_impl(jvmtiError err, const char* file, int line) {
  if (err != JVMTI_ERROR_NONE) {
    char* name = NULL;
    ourJVMTI->GetErrorName(err, &name);
    fprintf(stderr, "ERROR: JVMTI error err=%d(%s) in %s:%d\n", err, name, file, line);
    fflush(stderr);
    ourJVMTI->Deallocate((unsigned char *)name);
    assert(false);
  }
}

#define CALL_JVMTI(call_expr) check_JVMTI_error_impl(ourJVMTI->call_expr, __FILE__, __LINE__)

jint JNICALL my_callback(jlong class_tag, jlong size, jlong* tag_ptr, jint array_length, void*) {
  if (size < 0) {
    printf("negative size: array_length=%d\n", array_length);
  }

  return JVMTI_VISIT_OBJECTS;
}

extern "C" JNIEXPORT void JNICALL Java_NegativeArraySize_iterateHeap(JNIEnv* jni, jclass) {
  jvmtiHeapCallbacks callbacks;
  ZERO(callbacks);
  callbacks.heap_iteration_callback = &my_callback;

  CALL_JVMTI(
    IterateThroughHeap(JVMTI_HEAP_FILTER_TAGGED, NULL, &callbacks, NULL)
  );
}

extern "C" JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM* vm, char* options, void* /*reserved*/) {
  vm->GetEnv((void **)&ourJVMTI, JVMTI_VERSION);

  assert(ourJVMTI);

  jvmtiCapabilities capabilities;
  ZERO(capabilities);
  capabilities.can_tag_objects = 1;

  CALL_JVMTI(AddCapabilities(&capabilities));

  return 0;
}


---------- END SOURCE ----------

                                    

Comments
EVALUATION

class CallbackWrapper in jvmtiTagMap.cpp has a missing cast which leads to an integer overflow.

The code in question is
    _obj_size = _o->size() * wordSize;

_obj_size is a jlong
_o->size() is an int
wordSize is an int

Changing to:
    _obj_size = (jlong)_o->size() * wordSize;

fixes the overflow.
                                     
2012-06-25
EVALUATION

http://hg.openjdk.java.net/hsx/hotspot-rt/hotspot/rev/588f559105c1
                                     
2012-06-25
EVALUATION

http://hg.openjdk.java.net/lambda/lambda/hotspot/rev/588f559105c1
                                     
2012-06-29



Hardware and Software, Engineered to Work Together