Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4140915

C code cannot invoke a VM and set /catch breakpoints

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 1.2.0
    • core-svc
    • x86
    • windows_95



      Name: rm29839 Date: 05/21/98


      (JDK1.2beta3 Win95)

      I am trying to use C to invoke a VM, load a class, set breakpoints in the class (using JVMDI), run that class and catch the
      breakpoints. This does not work. After hitting the first breakpoint the program crashes.

      This code works if i create a dll and load it with a java class, setting breakpoints in the class via the dll. This works correctly.

      Is this expected behavior?

      thanks
      chadd williams

      /**** test2.c ****/
      /* this code creates the DLL called by the java class */
      #include "Test2.h"
      #include <JVMDI.H>

      JavaVM *remoteJVM;
      JNIEnv *remoteJE;
      jclass bkptClassObj;
      jint bkptCountPtr;
      JVMDI_line_number_entry *bkptTable;

      void hook(JNIEnv *env, JVMDI_Event *event) {
          printf("Hook is called.\n");
          if ( event->kind == JVMDI_EVENT_BREAKPOINT ) {
              printf("BP hit\n");
      JVMDI_ResumeThread(env, event->u.breakpoint.thread);
          } else {
      printf("Other event occurrred: %d\n",event->kind);
          }
      }

      jint Java_RemoteDebugger_nativeSetBreakpoint(jint lineNumb, char *methodName, char *className, char *sig){

      jmethodID mid;
      int i;
      char *namePtr[1];
      jint methodCountPtr;
      jmethodID **methodsPtr;
      jvmdiError res;

      mid = (*remoteJE)->GetMethodID(remoteJE, bkptClassObj, methodName, sig);
      if (mid == 0) {
      (*remoteJE)->ExceptionClear(remoteJE);
      mid = (*remoteJE)->GetStaticMethodID(remoteJE, bkptClassObj, methodName, sig);
      if (mid == 0) {
      (*remoteJE)->ExceptionClear(remoteJE);
      return -1;
      }
      }

      JVMDI_Deallocate(remoteJE, bkptTable);
      res = JVMDI_GetLineNumberTable(remoteJE, bkptClassObj, mid, &bkptCountPtr, &bkptTable);
      for(i = 0; i< bkptCountPtr; i++){
      if( bkptTable[i].line_number == lineNumb){
      JVMDI_SetBreakpoint(remoteJE, bkptClassObj, mid, bkptTable[i].start_location);
      break;
      }
      }
      return 1;
      }

      /*
      void Java_RemoteDebugger_nativeRun(int argc, char **argv){
      jmethodID mid;
      jobjectArray args;
      jstring jstr;

      jstr = (*remoteJE)->NewStringUTF(remoteJE, " ");
      args = (*remoteJE)->NewObjectArray(remoteJE, 1, (*remoteJE)->FindClass(remoteJE,"java/lang/String"),jstr);
      mid = (*remoteJE)->GetStaticMethodID(remoteJE, mainClass, "main", "([Ljava/lang/String;)V");
          if (mid == 0) {
              fprintf(stderr, "Can't find main()\n");
          }else{
      (*remoteJE)->CallStaticVoidMethod(remoteJE, mainClass, mid, args);
      }
      }
      */

      JNIEXPORT void JNICALL Java_Test2_startDebugger(JNIEnv *env, jclass cls) {

      jmethodID mid;
      jstring jstr;
      jobjectArray args;
      /*
      char **sargs;
       */
      remoteJE = env;
      bkptClassObj = cls;
      /*
      JNI_GetDefaultJavaVMInitArgs(&vm_args);
      options[0].name = "classpath";
      options[0].value.p = classpath;
      vm_args.version = 0x00010002;
      vm_args.options = options;
      vm_args.nOptions = 1;
          vm_args.result = &res;

          res = JNI_CreateJavaVM(&remoteJVM,&remoteJE,&vm_args);
      if (res < 0 ){
      fprintf(stderr, "Error invoking the JVM");
      return JVM_CREATE_ERROR;
      }
          mainClass = (*remoteJE)->FindClass(remoteJE, "Test2");
       

      */
          jstr = (*remoteJE)->NewStringUTF(remoteJE, "");
          if (jstr == 0) {
              fprintf(stderr, "Out of memory\n");
          }

          args = (*remoteJE)->NewObjectArray(remoteJE, 1,(*remoteJE)->FindClass(remoteJE, "java/lang/String"), jstr);
          if (args == 0) {
              fprintf(stderr, "Out of memory\n");
          }

          Java_RemoteDebugger_nativeSetBreakpoint(32, "main", "Test", "([Ljava/lang/String;)V" );
          Java_RemoteDebugger_nativeSetBreakpoint(34, "main", "Test", "([Ljava/lang/String;)V");
        JVMDI_SetEventHook(remoteJE, hook);

      /*
      Java_RemoteDebugger_nativeRun(0,sargs);
      */
      }



      /**** test2.java ***/
      public class Test2 {
          static {//disable when the C file invokes the VM
            System.loadLibrary("Test2"); // load dll
            startDebugger(); // start native method, set breakpoints
          }
          static native void startDebugger();

          static int x;
          static String y;

          public static void printX(){
              System.err.println(x);
          }

          public static void printY(){
              System.err.println(y);
          }

          public static void setX(int arg){
              x = arg;
          }

          public static void setY(String arg){
              y = arg;
          }

          public static void main(String args[]){

              System.err.println("BEGIN");
              y = new String("HELLO");
              printX();
              printY();
              setX(0);
              setY("TESTING");
              printY();
              printX();
              System.err.println("DONE");
          }
      }



      /* test2.c **************/
      /* this code invokes a VM and tries to catch breakpoints */
      #include <jvmdi.h>
      #include <jni.h>

      JavaVM *remoteJVM;
      JNIEnv *remoteJE;

      jthread currentVMThread;
      jobject runtimeObject;
      jclass runtimeClass;
      jclass mainClass;

      JVMDI_line_number_entry *bkptTable;
      jint bkptCountPtr;
      jclass bkptClassObj;
      char bkptClassName[80];

      void Java_RemoteDebugger_nativeCont();


      void hook(JNIEnv *env, JVMDI_Event *event){
          printf("Hook is called.\n");
          if ( event->kind == JVMDI_EVENT_BREAKPOINT ) {
              printf("BP hit\n");
      JVMDI_ResumeThread(env, event->u.breakpoint.thread);
          } else {
      printf("Other event occurrred: %d\n",event->kind);
          }
          return;
      }

      /*
       * Class: RemoteDebugger
       * Method: nativeFindClass
       * Signature: (Ljava/lang/String;)V
       */
      int Java_RemoteDebugger_nativeFindClass(const char *classname){

          mainClass = (*remoteJE)->FindClass(remoteJE, classname);
          if (mainClass == 0) {
              fprintf(stderr, "Can't find %s\n",classname);
      return -1;
          }
      return 0;
      }


      /*
       * Class: RemoteDebugger
       * Method: nativeRun
       * Signature: (I[Ljava/lang/String;)V
       */
       void Java_RemoteDebugger_nativeRun(int argc, char **argv){
      jmethodID mid;
      jobjectArray args;
      jstring jstr;

      jstr = (*remoteJE)->NewStringUTF(remoteJE, " ");
      args = (*remoteJE)->NewObjectArray(remoteJE, 1, (*remoteJE)->FindClass(remoteJE,"java/lang/String"),jstr);
      mid = (*remoteJE)->GetStaticMethodID(remoteJE, mainClass, "main", "([Ljava/lang/String;)V");
          if (mid == 0) {
              fprintf(stderr, "Can't find main()\n");
          }else{
      /* convert **argv to what*/
      (*remoteJE)->CallStaticVoidMethod(remoteJE, mainClass, mid, args);
      }
      }


      /*
       * Class: RemoteDebugger
       * Method: nativeSetBreakpoint
       * Signature: (ILjava/lang/String;Ljava/lang/String;)I
       */
      jint Java_RemoteDebugger_nativeSetBreakpoint(jint lineNumb, char *methodName, char *className, char *sig){

      jmethodID mid;
      int i;
      long k;
      char *namePtr[1];
      jint methodCountPtr;
      jmethodID **methodsPtr;
      jvmdiError res;

      bkptClassObj = (*remoteJE)->FindClass(remoteJE, className);

      if (bkptClassObj == 0) {
      fprintf(stderr, "Can't find class %s\n",className);
      }
      mid = (*remoteJE)->GetMethodID(remoteJE, bkptClassObj, methodName, sig);
      if (mid == 0) {
      (*remoteJE)->ExceptionClear(remoteJE);
      mid = (*remoteJE)->GetStaticMethodID(remoteJE, bkptClassObj, methodName, sig);
      if (mid == 0) {
      (*remoteJE)->ExceptionClear(remoteJE);
      fprintf(stderr, "Can't find method %s\n", methodName);
      return -1;
      }
      }

      JVMDI_Deallocate(remoteJE, bkptTable);
      res = JVMDI_GetLineNumberTable(remoteJE, bkptClassObj, mid, &bkptCountPtr, &bkptTable);
      switch(res){
      case JVMDI_ERROR_NONE :
      fprintf(stderr, "NONE");
      break;
      case JVMDI_ERROR_NULL_POINTER :
      fprintf(stderr, "NULL POINTER");
      break;
      case JVMDI_ERROR_INVALID_METHODID :
      fprintf(stderr, "INVALID METHODID");
      break;
      case JVMDI_ERROR_INVALID_CLASS :
      fprintf(stderr, "INVALID CLASS");
      break;
      case JVMDI_ERROR_OUT_OF_MEMORY :
      fprintf(stderr, "OUT OF MEMORY");
      break;
      case JVMDI_ERROR_ABSENT_INFORMATION :
      fprintf(stderr, "ABSENT INFORMATION");
      break;
      }

      k = bkptCountPtr;
      strcpy(bkptClassName,className);
      for(i = 0; i< k; i++){
      if( bkptTable[i].line_number == lineNumb){
      JVMDI_SetBreakpoint(remoteJE, bkptClassObj, mid, bkptTable[i].start_location);
      fprintf(stderr, " breakpoint set ");
      break;
      }
      }
      return 1;
      }




      /*
       * Class: RemoteDebugger
       * Method: nativeCreateVM
       * Signature: ()V
       */
      int Java_RemoteDebugger_nativeCreateVM(char classpath[]){

      JavaVMOption options[1];
      JavaVMInitArgs vm_args;
      jmethodID mid;
      jstring jstr;
      jobjectArray args;
      long res;
      char **sargs;
      jvmdiError jError;

      JNI_GetDefaultJavaVMInitArgs(&vm_args);
      options[0].name = "classpath";
      options[0].value.p = classpath;

      vm_args.version = 0x00010002;
      vm_args.options = options;
      vm_args.nOptions = 1;
          vm_args.result = &res;

          res = JNI_CreateJavaVM(&remoteJVM,&remoteJE,&vm_args);
      if (res < 0 ){
      fprintf(stderr, "Error invoking the JVM");
      return -1;
      }


          jstr = (*remoteJE)->NewStringUTF(remoteJE, "");
          if (jstr == 0) {
              fprintf(stderr, "Out of memory\n");
          }
          args = (*remoteJE)->NewObjectArray(remoteJE, 1,(*remoteJE)->FindClass(remoteJE, "java/lang/String"), jstr);
          if (args == 0) {
              fprintf(stderr, "Out of memory\n");
          }

          if( Java_RemoteDebugger_nativeFindClass("Test") == -1 ){
      fprintf(stderr," ERROR ABORTING\n");
      }
            Java_RemoteDebugger_nativeSetBreakpoint(32, "main", "Test", "([Ljava/lang/String;)V" );
      jError = JVMDI_SetEventHook(remoteJE, hook);
          Java_RemoteDebugger_nativeRun(0,sargs);
      return 0;
      }


      int main(){
      int result;

      result = Java_RemoteDebugger_nativeCreateVM("d:\\jdk1.2beta3\\lib\\classes.zip;D:\\data\\Source\\Java\\jdk1.2beta2\\JVMDItest\\Debug");

      }
      (Review ID: 29143)
      ======================================================================

            Unassigned Unassigned
            rmandelsunw Ronan Mandel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: