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)
======================================================================
- duplicates
-
JDK-4124967 JVMDI does not set or check for debugging mode
-
- Closed
-