United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: 5097131 ClassFileLoadHook can be called with classname==NULL, hprof & demos could SEGV
5097131 : ClassFileLoadHook can be called with classname==NULL, hprof & demos could SEGV

Details
Type:
Bug
Submit Date:
2004-09-04
Status:
Resolved
Updated Date:
2004-10-11
Project Name:
JDK
Resolved Date:
2004-10-09
Component:
core-svc
OS:
generic
Sub-Component:
tools
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:
6

Related Reports
Backport:
Relates:

Sub Tasks

Description
ClassFileLoadHook can be called with classname==NULL, hprof & demos could SEGV
when this happens.

Need to add in some null pointer checks into the hprof, mtrace, and heapTracker
demos.

                                    

Comments
PUBLIC COMMENTS

Also see bug 5096167. If the JVMTI ClassFileLoadHook interface does return NULL 
for the class name, the demos hprof, mtrace, and heapTracker could cause a 
SEGV and trigger a VM crash.
                                     
2004-09-28
SUGGESTED FIX

HeapTracker demo, hprof demo, and java_crw_demo changes:

----------------------------------------------------------------------------
heapTracker demo:

------- heapTracker.c -------
*** /tmp/sccs.efaiBv	Thu Sep 23 16:01:22 2004
--- heapTracker.c	Fri Sep 17 09:21:48 2004
***************
*** 1,5 ****
  /*
!  * @(#)heapTracker.c	1.7 04/07/27
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
--- 1,5 ----
  /*
!  * @(#)heapTracker.c	1.10 04/09/17
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
***************
*** 791,801 ****
  	/* It's possible we get here right after VmDeath event, be careful */
  	if ( !gdata->vmDead ) {
  
              *new_class_data_len = 0;
              *new_class_data     = NULL;
  
              /* The tracker class itself? */
!             if ( strcmp(name, STRING(HEAP_TRACKER_class)) != 0 ) {
                  jint           cnum;
                  int            systemClass;
                  unsigned char *newImage;
--- 791,817 ----
  	/* It's possible we get here right after VmDeath event, be careful */
  	if ( !gdata->vmDead ) {
  
+ 	    const char * classname;
+ 
+ 	    /* Name can be NULL, make sure we avoid SEGV's */
+ 	    if ( name == NULL ) {
+ 		classname = java_crw_demo_classname(class_data, class_data_len,
+ 				NULL);
+ 		if ( classname == NULL ) {
+ 		    fatal_error("ERROR: No classname in classfile\n");
+ 		}
+             } else {
+ 	        classname = strdup(name);
+ 		if ( classname == NULL ) {
+ 		    fatal_error("ERROR: Ran out of malloc() space\n");
+ 		}
+             }
+ 
  	    *new_class_data_len = 0;
              *new_class_data     = NULL;
  
              /* The tracker class itself? */
!             if ( strcmp(classname, STRING(HEAP_TRACKER_class)) != 0 ) {
                  jint           cnum;
                  int            systemClass;
                  unsigned char *newImage;
***************
*** 818,824 ****
  
                  /* Call the class file reader/write demo code */
                  java_crw_demo(cnum,
!                     name,
                      class_data,
                      class_data_len,
                      systemClass,
--- 834,840 ----
  
                  /* Call the class file reader/write demo code */
                  java_crw_demo(cnum,
!                     classname,
                      class_data,
                      class_data_len,
                      systemClass,
***************
*** 850,855 ****
--- 866,873 ----
                      (void)free((void*)newImage); /* Free malloc() space with free() */
                  }
              }
+ 	
+ 	    (void)free((void*)classname);
  	}
      } exitCriticalSection(jvmti);
  }
 
 
----------------------------------------------------------------------------
Hprof:


------- hprof.h -------
*** /tmp/sccs.4iaqCv	Thu Sep 23 16:01:23 2004
--- hprof.h	Fri Sep 17 10:58:08 2004
***************
*** 1,5 ****
  /*
!  * @(#)hprof.h	1.39 04/07/27
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
--- 1,5 ----
  /*
!  * @(#)hprof.h	1.41 04/09/17
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
***************
*** 357,362 ****
--- 367,373 ----
      /* Handles to java_crw_demo library */
      void * java_crw_demo_library;
      void * java_crw_demo_function;
+     void * java_crw_demo_classname_function;
  
  } GlobalData;
  
 
 

------- hprof_init.c -------
*** /tmp/sccs.9oaGEv	Thu Sep 23 16:01:23 2004
--- hprof_init.c	Fri Sep 17 09:22:42 2004
***************
*** 1,5 ****
  /*
!  * @(#)hprof_init.c	1.80 04/07/27
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
--- 1,5 ----
  /*
!  * @(#)hprof_init.c	1.83 04/09/17
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 

***************
*** 1373,1379 ****
  
      /* WARNING: This will be called before VM_INIT. */
  
!     LOG2("cbClassFileLoadHook:",name);
      
      if (!gdata->bci) {
          return;
--- 1373,1379 ----
  
      /* WARNING: This will be called before VM_INIT. */
  
!     LOG2("cbClassFileLoadHook:",(name==NULL?"Unknown":name));
      
      if (!gdata->bci) {
          return;
***************
*** 1381,1386 ****
--- 1381,1387 ----
      
      BEGIN_CALLBACK() {
  	rawMonitorEnter(gdata->data_access_lock); {
+ 	    const char *classname;
  	    
  	    if ( gdata->bci_counter == 0 ) {
  		/* Prime the system classes */
***************
*** 1392,1399 ****
  	    *new_class_data_len = 0;
  	    *new_class_data     = NULL;
  
  	    /* The tracker class itself? */
! 	    if ( strcmp(name,"sun/tools/hprof/Tracker") != 0 ) {
  		ClassIndex            cnum;
  		int                   system_class;
  		unsigned char *       new_image;
--- 1393,1415 ----
  	    *new_class_data_len = 0;
  	    *new_class_data     = NULL;
  
+ 	    /* Name could be NULL */
+ 	    if ( name == NULL ) {
+ 		classname = ((JavaCrwDemoClassname)
+ 			     (gdata->java_crw_demo_classname_function))
+ 		    (class_data, class_data_len, &my_crw_fatal_error_handler);
+ 		if ( classname == NULL ) {
+ 		    HPROF_ERROR(JNI_TRUE, "No classname in classfile");
+ 		}
+ 	    } else {
+ 		classname = strdup(name);
+ 		if ( classname == NULL ) {
+ 		    HPROF_ERROR(JNI_TRUE, "Ran out of malloc() space");
+ 		}
+ 	    }
+ 	    
  	    /* The tracker class itself? */
! 	    if ( strcmp(classname,"sun/tools/hprof/Tracker") != 0 ) {
  		ClassIndex            cnum;
  		int                   system_class;
  		unsigned char *       new_image;
***************
*** 1402,1414 ****
                  char                 *signature;
  		LoaderIndex           loader_index;
  		
! 		LOG2("cbClassFileLoadHook injecting class" , name);
  		
  		/* Define a unique class number for this class */
! 		len              = (int)strlen(name);
  		signature        = HPROF_MALLOC(len+3);
  		signature[0]     = JVM_SIGNATURE_CLASS;
! 		(void)memcpy(signature+1, name, len);
  		signature[len+1] = JVM_SIGNATURE_ENDCLASS;
  		signature[len+2] = 0;
  		loader_index = loader_find_or_create(env,loader);
--- 1418,1430 ----
                  char                 *signature;
  		LoaderIndex           loader_index;
  		
! 		LOG2("cbClassFileLoadHook injecting class" , classname);
  		
  		/* Define a unique class number for this class */
! 		len              = (int)strlen(classname);
  		signature        = HPROF_MALLOC(len+3);
  		signature[0]     = JVM_SIGNATURE_CLASS;
! 		(void)memcpy(signature+1, classname, len);
  		signature[len+1] = JVM_SIGNATURE_ENDCLASS;
  		signature[len+2] = 0;
  		loader_index = loader_find_or_create(env,loader);
***************
*** 1430,1436 ****
  		     && ( ( class_get_status(cnum) & CLASS_SYSTEM) != 0
  			    || gdata->bci_counter < 8 ) ) {
  		    system_class = 1;
! 		    LOG2(name, " is a system class");
  		}
  
  		new_image = NULL;
--- 1446,1452 ----
  		     && ( ( class_get_status(cnum) & CLASS_SYSTEM) != 0
  			    || gdata->bci_counter < 8 ) ) {
  		    system_class = 1;
! 		    LOG2(classname, " is a system class");
  		}
  
  		new_image = NULL;
***************
*** 1439,1445 ****
  		/* Call the class file reader/write demo code */
  		((JavaCrwDemo)(gdata->java_crw_demo_function))(
  		    cnum, 
! 		    name, 
  		    class_data, 
  		    class_data_len, 
  	            system_class,
--- 1455,1461 ----
  		/* Call the class file reader/write demo code */
  		((JavaCrwDemo)(gdata->java_crw_demo_function))(
  		    cnum, 
! 		    classname, 
  		    class_data, 
  		    class_data_len, 
  	            system_class,
***************
*** 1461,1473 ****
  		if ( new_length > 0 ) {
  		    unsigned char *jvmti_space;
  		    
! 		    LOG2("cbClassFileLoadHook DID inject this class", name);
  		    jvmti_space = (unsigned char *)jvmtiAllocate((jint)new_length);
  		    (void)memcpy((void*)jvmti_space, (void*)new_image, (int)new_length);
  		    *new_class_data_len = (jint)new_length;
  		    *new_class_data     = jvmti_space; /* VM will deallocate */
  		} else {
! 		    LOG2("cbClassFileLoadHook DID NOT inject this class", name);
  		    *new_class_data_len = 0;
  		    *new_class_data     = NULL;
  	        }
--- 1477,1489 ----
  		if ( new_length > 0 ) {
  		    unsigned char *jvmti_space;
  		    
! 		    LOG2("cbClassFileLoadHook DID inject this class", classname);
  		    jvmti_space = (unsigned char *)jvmtiAllocate((jint)new_length);
  		    (void)memcpy((void*)jvmti_space, (void*)new_image, (int)new_length);
  		    *new_class_data_len = (jint)new_length;
  		    *new_class_data     = jvmti_space; /* VM will deallocate */
  		} else {
! 		    LOG2("cbClassFileLoadHook DID NOT inject this class", classname);
  		    *new_class_data_len = 0;
  		    *new_class_data     = NULL;
  	        }
***************
*** 1475,1480 ****
--- 1491,1497 ----
  		    (void)free((void*)new_image); /* Free malloc() space with free() */
  		}
  	    }
+ 	    (void)free((void*)classname);
  	} rawMonitorExit(gdata->data_access_lock);
      } END_CALLBACK();
  }
***************
*** 1781,1786 ****
--- 1798,1855 ----
  
  }
  
+ /* Dynamic library loading */
+ static void *
+ load_library(char *name)
+ {
+     char  lname[FILENAME_MAX+1];
+     char  err_buf[256+FILENAME_MAX+1];
+     char *boot_path;
+     void *handle;
+ 
+     handle = NULL;
+ 
+     /* The library may be located in different ways, try both, but
+      *   if it comes from outside the SDK/jre it isn't ours.
+      */
+     getSystemProperty("sun.boot.library.path", &boot_path);
+     md_build_library_name(lname, FILENAME_MAX, boot_path, name);
+     handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
+     if ( handle == NULL ) {
+ 	/* This may be necessary on Windows. */
+ 	md_build_library_name(lname, FILENAME_MAX, "", name);
+ 	handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
+ 	if ( handle == NULL ) {
+ 	    HPROF_ERROR(JNI_TRUE, err_buf);
+ 	}
+     }
+     return handle;
+ }
+ 
+ /* Lookup dynamic function pointer in shared library */
+ static void *
+ lookup_library_symbol(void *library, char **symbols, int nsymbols)
+ {
+     void *addr;
+     int   i;
+ 
+     addr = NULL;
+     for( i = 0 ; i < nsymbols; i++ ) {
+ 	addr = md_find_library_entry(library, symbols[i]);
+ 	if ( addr != NULL ) {
+ 	    break;
+ 	}
+     }
+     if ( addr == NULL ) {
+ 	char errmsg[256];
+ 	
+ 	(void)md_snprintf(errmsg, sizeof(errmsg), 
+ 		    "Cannot find library symbol '%s'", symbols[0]);
+ 	HPROF_ERROR(JNI_TRUE, errmsg);
+     }
+     return addr;
+ }
+ 
  /* ------------------------------------------------------------------- */
  /* The OnLoad interface */
  
***************
*** 1859,1900 ****
  
      /* Load java_crw_demo library and find function "java_crw_demo" */
      if ( gdata->bci ) {
- 	static char *symbols[] = JAVA_CRW_DEMO_SYMBOLS; /* "java_crw_demo" */
- 	char         lname[FILENAME_MAX+1];
- 	char         err_buf[256+FILENAME_MAX+1];
- 	char        *boot_path;
- 	int          i;
  
! 	/* The library may be located in different ways, try both, but
! 	 *   if it comes from outside the SDK/jre it isn't ours.
! 	 *   But with a name like java_crw_demo, what are the odds?
! 	 */
! 	getSystemProperty("sun.boot.library.path", &boot_path);
! 	md_build_library_name(lname, FILENAME_MAX, boot_path, "java_crw_demo");
! 	gdata->java_crw_demo_library = 
! 	         md_load_library(lname, err_buf, (int)sizeof(err_buf));
! 	if ( gdata->java_crw_demo_library == NULL ) {
! 	    /* This may be necessary on Windows. */
! 	    md_build_library_name(lname, FILENAME_MAX, "", "java_crw_demo");
! 	    gdata->java_crw_demo_library = 
! 		     md_load_library(lname, err_buf, (int)sizeof(err_buf));
! 	    if ( gdata->java_crw_demo_library == NULL ) {
! 		HPROF_ERROR(JNI_TRUE, err_buf);
! 	    }
! 	}
  	
! 	/* The function may have different names, we find the first one */
! 	for( i = 0 ; i < (int)(sizeof(symbols)/sizeof(char*)) ; i++ ) {
  	    gdata->java_crw_demo_function = 
! 	      md_find_library_entry(gdata->java_crw_demo_library, symbols[i]);
! 	    if ( gdata->java_crw_demo_function != NULL ) {
! 		break;
  	    }
  	}
- 	if ( gdata->java_crw_demo_function == NULL ) {
- 	    HPROF_ERROR(JNI_TRUE, "Cannot find java_crw_demo function.");
  	}
-     }
      
      return JNI_OK;
  }
--- 1928,1950 ----
  
      /* Load java_crw_demo library and find function "java_crw_demo" */
      if ( gdata->bci ) {
  
! 	/* Load the library or get the handle to it */
! 	gdata->java_crw_demo_library = load_library("java_crw_demo"); 
  	
! 	{ /* "java_crw_demo" */
! 	    static char *symbols[]  = JAVA_CRW_DEMO_SYMBOLS;
  	    gdata->java_crw_demo_function = 
! 	           lookup_library_symbol(gdata->java_crw_demo_library, 
! 			      symbols, (int)(sizeof(symbols)/sizeof(char*)));
  	}
+ 	{ /* "java_crw_demo_classname" */
+ 	    static char *symbols[] = JAVA_CRW_DEMO_CLASSNAME_SYMBOLS;
+ 	    gdata->java_crw_demo_classname_function = 
+ 	           lookup_library_symbol(gdata->java_crw_demo_library, 
+ 			      symbols, (int)(sizeof(symbols)/sizeof(char*)));
          }
      }
      
      return JNI_OK;
  }
 
 
----------------------------------------------------------------------------

java_crw_demo:

------- java_crw_demo.c -------
*** /tmp/sccs.pHaaJv	Thu Sep 23 16:01:24 2004
--- java_crw_demo.c	Fri Sep 17 09:24:09 2004
***************
*** 1,5 ****
  /*
!  * @(#)java_crw_demo.c	1.20 04/07/27
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
--- 1,5 ----
  /*
!  * @(#)java_crw_demo.c	1.23 04/09/17
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 

***************
*** 285,300 ****
      void * ptr;
     
      ptr = malloc(nbytes);
      return ptr;
  }
  
  static void *
  allocate_clean(CrwClassImage *ci, int nbytes)
  {
      void * ptr;
     
!     ptr = allocate(ci, nbytes);
!     (void)memset(ptr, 0, nbytes);
      return ptr;
  }
  
--- 282,314 ----
      void * ptr;
     
      ptr = malloc(nbytes);
+     if ( ptr == NULL ) {
+ 	CRW_FATAL(ci, "Ran out of malloc memory"); 
+     }
      return ptr;
  }
  
  static void *
+ reallocate(CrwClassImage *ci, void *optr, int nbytes)
+ {
+     void * ptr;
+    
+     ptr = realloc(optr, nbytes);
+     if ( ptr == NULL ) {
+ 	CRW_FATAL(ci, "Ran out of malloc memory"); 
+     }
+     return ptr;
+ }
+ 
+ static void *
  allocate_clean(CrwClassImage *ci, int nbytes)
  {
      void * ptr;
     
!     ptr = calloc(nbytes, 1);
!     if ( ptr == NULL ) {
! 	CRW_FATAL(ci, "Ran out of malloc memory"); 
!     }
      return ptr;
  }
  
***************
*** 356,363 ****
--- 370,379 ----
  writeU1(CrwClassImage *ci, unsigned val)  /* Only writes out lower 8 bits */
  {
      CRW_ASSERT_CI(ci);
+     if ( ci->output != NULL ) {
          ci->output[ci->output_position++] = val & 0xFF;
      }
+ }
  
  static void 
  writeU2(CrwClassImage *ci, unsigned val) 
***************
*** 666,673 ****
--- 682,691 ----
  	}
      }
  
+   
                                     
2004-09-28
CONVERTED DATA

BugTraq+ Release Management Values

COMMIT TO FIX:
mustang

FIXED IN:
mustang


                                     
2004-09-28
SUGGESTED FIX

  if (  ci->tclass_name != NULL ) {
  	ci->tracker_class_index = 
                  add_new_class_cpool_entry(ci, ci->tclass_name);
+     }
      if (ci->obj_init_name != NULL) {
          ci->object_init_tracker_index = add_new_method_cpool_entry(ci, 
                      ci->tracker_class_index, 

***************
*** 2121,2127 ****
  
      /* Do the injection */
      max_length = file_len*2 + 512; /* Twice as big + 512 */
!     new_image = malloc((int)max_length);
      new_length = inject_class(&ci, 
  				 system_class, 
  				 tclass_name,     
--- 2152,2158 ----
  
      /* Do the injection */
      max_length = file_len*2 + 512; /* Twice as big + 512 */
!     new_image = allocate(&ci, (int)max_length);
      new_length = inject_class(&ci, 
  				 system_class, 
  				 tclass_name,     
***************
*** 2139,2148 ****
     
      /* Dispose or shrink the space to be returned. */
      if ( new_length == 0 ) {
! 	(void)free(new_image);
  	new_image = NULL;
      } else {
!         new_image = (void*)realloc((void*)new_image, (int)new_length);
      }
     
      /* Return the new class image */
--- 2170,2179 ----
     
      /* Dispose or shrink the space to be returned. */
      if ( new_length == 0 ) {
! 	deallocate(&ci, (void*)new_image);
  	new_image = NULL;
      } else {
!         new_image = (void*)reallocate(&ci, (void*)new_image, (int)new_length);
      }
     
      /* Return the new class image */
***************
*** 2153,2155 ****
--- 2184,2240 ----
      cleanup(&ci);
  }
  
+ /* Return the classname for this class which is inside the classfile image. */
+ JNIEXPORT char * JNICALL 
+ java_crw_demo_classname(const unsigned char *file_image, long file_len,
+ 	FatalErrorHandler fatal_error_handler)
+ {
+     CrwClassImage               ci;
+     CrwConstantPoolEntry        cs;
+     CrwCpoolIndex               this_class;
+     unsigned                    magic;
+     char *                      name;
+ 
+     name = NULL;
+     
+     if ( file_len==0 || file_image==NULL ) {
+ 	return name;
+     }
+ 
+     /* The only fields we need filled in are the image pointer and the error
+      *    handler.
+      *    By not adding an output buffer pointer, no output is created.
+      */
+     (void)memset(&ci, 0, (int)sizeof(CrwClassImage));
+     ci.input     = file_image;
+     ci.input_len = file_len;
+     ci.fatal_error_handler = fatal_error_handler;
+ 
+     /* Read out the bytes from the classfile image */
+ 
+     magic = readU4(&ci); /* magic number */
+     CRW_ASSERT(&ci, magic==0xCAFEBABE);
+     if ( magic != 0xCAFEBABE ) {
+ 	return name;
+     }
+     (void)readU2(&ci); /* minor version number */
+     (void)readU2(&ci); /* major version number */
+    
+     /* Read in constant pool. Since no output setup, writes are NOP's */
+     cpool_setup(&ci);
+ 
+     (void)readU2(&ci); /* access flags */
+     this_class = readU2(&ci); /* 'this' class */
+    
+     /* Get 'this' constant pool entry */
+     cs = cpool_entry(&ci, (CrwCpoolIndex)(cpool_entry(&ci, this_class).index1));
+     
+     /* Duplicate the name */
+     name = (char *)duplicate(&ci, cs.ptr, cs.len);
+     
+     /* Cleanup before we leave. */
+     cleanup(&ci);
+ 
+     /* Return malloc space */
+     return name;
+ }
 
 

------- java_crw_demo.h -------
*** /tmp/sccs.CMaiKv	Thu Sep 23 16:01:25 2004
--- java_crw_demo.h	Fri Sep 17 09:20:05 2004
***************
*** 1,5 ****
  /*
!  * @(#)java_crw_demo.h	1.13 04/07/27
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
--- 1,5 ----
  /*
!  * @(#)java_crw_demo.h	1.15 04/09/17
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
***************
*** 159,163 ****
--- 159,185 ----
  	   
  	   );
  
+ 
+ /* External to read the class name out of a class file .
+  *
+  *   WARNING: If You change the typedef, you MUST change
+  *            multiple things in this file, including this name.
+  */
+ 
+ #define JAVA_CRW_DEMO_CLASSNAME_SYMBOLS + 	 { "java_crw_demo_classname", "_java_crw_demo_classname@12" }
+ 
+ /* Typedef needed for type casting in dynamic access situations. */
+ 
+ typedef char * (JNICALL *JavaCrwDemoClassname)(
+ 	 const unsigned char *file_image, 
+ 	 long file_len, 
+ 	 FatalErrorHandler fatal_error_handler);
+ 
+ JNIEXPORT char * JNICALL java_crw_demo_classname(
+          const unsigned char *file_image, 
+ 	 long file_len, 
+ 	 FatalErrorHandler fatal_error_handler);
+ 
  #endif
  
 
 
----------------------------------------------------------------------------

mtrace demo:

------- mtrace.c -------
*** /tmp/sccs.nPaqLv	Thu Sep 23 16:01:25 2004
--- mtrace.c	Fri Sep 17 09:21:10 2004
***************
*** 1,5 ****
  /*
!  * @(#)mtrace.c	1.23 04/07/27
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
--- 1,5 ----
  /*
!  * @(#)mtrace.c	1.26 04/09/17
   * 
   * Copyright (c) 2004 Sun Microsystems, Inc. All Rights Reserved.
   * 
***************
*** 269,277 ****
--- 269,283 ----
  
  	mp            = cp->methods + mnum;
          mp->name      = (const char *)strdup(names[mnum]);
+ 	if ( mp->name == NULL ) {
+ 	    fatal_error("ERROR: Out of malloc memory\n");
+ 	}
          mp->signature = (const char *)strdup(sigs[mnum]);
+ 	if ( mp->signature == NULL ) {
+ 	    fatal_error("ERROR: Out of malloc memory\n");
  	}
      }
+ }
  
  /* Java Native Method for entry */
  static void
***************
*** 523,534 ****
  	/* It's possible we get here right after VmDeath event, be careful */
  	if ( !gdata->vm_is_dead ) {
  
              *new_class_data_len = 0;
              *new_class_data     = NULL;
  
              /* The tracker class itself? */
!             if ( interested((char*)name, "", gdata->include, gdata->exclude) 
! 		     &&  strcmp(name, STRING(MTRACE_class)) != 0 ) {
                  jint           cnum;
                  int            system_class;
                  unsigned char *new_image;
--- 529,556 ----
  	/* It's possible we get here right after VmDeath event, be careful */
  	if ( !gdata->vm_is_dead ) {
  
+ 	    const char *classname;
+ 
+             /* Name could be NULL */
+ 	    if ( name == NULL ) {
+ 		classname = java_crw_demo_classname(class_data, class_data_len,
+ 			NULL);
+ 		if ( classname == NULL ) {
+ 		    fatal_error("ERROR: No classname inside classfile\n");
+ 		}
+ 	    } else {
+ 		classname = strdup(name);
+ 		if ( classname == NULL ) {
+ 		    fatal_error("ERROR: Out of malloc memory\n");
+ 		}
+ 	    }
+ 	    
  	    *new_class_data_len = 0;
              *new_class_data     = NULL;
  
              /* The tracker class itself? */
!             if ( interested((char*)classname, "", gdata->include, gdata->exclude) 
! 		  &&  strcmp(classname, STRING(MTRACE_class)) != 0 ) {
                  jint           cnum;
                  int            system_class;
                  unsigned char *new_image;
***************
*** 551,557 ****
  		    fatal_error("ERROR: Out of malloc memory\n");
  		}
  		cp           = gdata->classes + cnum;
! 		cp->name     = (const char *)strdup(name);
  		cp->calls    = 0;
  		cp->mcount   = 0;
  		cp->methods  = NULL;
--- 573,582 ----
  		    fatal_error("ERROR: Out of malloc memory\n");
  		}
  		cp           = gdata->classes + cnum;
! 		cp->name     = (const char *)strdup(classname);
! 		if ( cp->name == NULL ) {
! 		    fatal_error("ERROR: Out of malloc memory\n");
! 		}
  		cp->calls    = 0;
  		cp->mcount   = 0;
  		cp->methods  = NULL;
***************
*** 570,576 ****
  
                  /* Call the class file reader/write demo code */
                  java_crw_demo(cnum,
!                     name,
                      class_data,
                      class_data_len,
                      system_class,
--- 595,601 ----
  
                  /* Call the class file reader/write demo code */
                  java_crw_demo(cnum,
!                     classname,
                      class_data,
                      class_data_len,
                      system_class,
***************
*** 601,606 ****
--- 626,632 ----
                      (void)free((void*)new_image); /* Free malloc() space with free() */
                  }
              }
+ 	    (void)free((void*)classname);
  	}
      } exit_critical_section(jvmti);
  }
 


###@###.### 2004-09-23
                                     
2004-09-23
EVALUATION

Just needs a null pointer check in the classfile load hook.

###@###.### 2004-09-03

hprof may have a bit of a snag here. It wants to create an entry for a class
in it's class table, and that has used it's name. It needed to do this before
the classfile image is passed on to the java_crw_demo for BCI because it needed
a unique ID for the injection.  Without the classname, it would need to dig
into the classfile and get it, a pain. I think hprof will still work ok,
but without extensive testing, I'm not sure what it will mean to have an empty
class name as it's search criteria.
I wish this classname==NULL was illegal, it certainly isn't something I would
want to allow forever.

Regardless, I think when JVMTI is fixed and hprof starts getting NULl classnames
that this bug will be fixed.  Still needs testing.

###@###.### 2004-09-05
                                     
2004-09-05



Hardware and Software, Engineered to Work Together