1 /* src/native/vm/VMVirtualMachine.c - jdwp->jvmti interface
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Martin Platter
32 $Id: VMVirtualMachine.c 4661 2006-03-21 00:04:59Z motse $
36 #include "toolbox/logging.h"
37 #include "native/jni.h"
38 #include "native/include/java_lang_Thread.h"
39 #include "native/include/java_nio_ByteBuffer.h"
40 #include "native/include/java_lang_Class.h"
41 #include "native/include/java_lang_ClassLoader.h"
42 #include "native/include/java_lang_reflect_Method.h"
43 #include "native/include/gnu_classpath_jdwp_event_EventRequest.h"
44 #include "native/include/gnu_classpath_jdwp_VMVirtualMachine.h"
45 #include "native/jvmti/jvmti.h"
46 #include "native/jvmti/cacaodbg.h"
51 * Class: gnu_classpath_jdwp_VMVirtualMachine
52 * Method: suspendThread
53 * Signature: (Ljava/lang/Thread;)V
55 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_suspendThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1)
57 (*remotedbgjvmtienv)->SuspendThread(remotedbgjvmtienv, (jthread) par1);
61 * Class: gnu_classpath_jdwp_VMVirtualMachine
62 * Method: resumeThread
63 * Signature: (Ljava/lang/Thread;)V
65 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_resumeThread(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1)
67 (*remotedbgjvmtienv)->ResumeThread(remotedbgjvmtienv, (jthread) par1);
72 * Class: gnu_classpath_jdwp_VMVirtualMachine
73 * Method: getSuspendCount
74 * Signature: (Ljava/lang/Thread;)I
76 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSuspendCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
77 log_text ("VMVirtualMachine_getSuspendCount: not supported");
82 * Class: gnu_classpath_jdwp_VMVirtualMachine
83 * Method: getAllLoadedClassesCount
86 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClassesCount(JNIEnv *env, jclass clazz) {
90 (*remotedbgjvmtienv)->GetLoadedClasses(remotedbgjvmtienv, &count, &classes);
95 * Class: gnu_classpath_jdwp_VMVirtualMachine
96 * Method: getAllLoadedClasses
97 * Signature: ()Ljava/util/Iterator
99 JNIEXPORT struct java_util_Iterator* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllLoadedClasses(JNIEnv *env, jclass clazz) {
100 jclass *classes, *cl;
110 if (JVMTI_ERROR_NONE != (err= (*remotedbgjvmtienv)->
111 GetLoadedClasses(remotedbgjvmtienv, &classcount, &classes))) {
112 (*remotedbgjvmtienv)->GetErrorName(remotedbgjvmtienv,err, &errdesc);
113 fprintf(stderr,"jvmti error: %s\n",errdesc);
115 /* env->ThrowNew(env,ec,"jvmti error occoured");*/
118 cl = (*env)->FindClass(env,"java.lang.Class");
120 /* Arrays.asList(Object[] classes)->List.Iterator()->Iterator */
121 joa = (*env)->NewObjectArray(env, (jsize)classcount, cl , NULL);
123 for (i = 0; i < classcount; i++)
124 (*env)->SetObjectArrayElement(env,joa,(jsize)i, (jobject)classes[i]);
126 cl = (*env)->FindClass(env,"java.util.Arrays");
127 if (!cl) return NULL;
129 m = (*env)->GetStaticMethodID(env, cl, "asList", "([Ljava/lang/Object;)Ljava/util/List;");
132 ol = (*env)->CallStaticObjectMethod(env,(jclass)cl,m,joa);
133 if (!ol) return NULL;
135 cl = (*env)->FindClass(env,"java.util.List");
136 if (!cl) return NULL;
137 m = (*env)->GetMethodID(env,cl,"Iterator","()Ljava/util/Iterator;");
139 oi = (*env)->CallObjectMethod(env,*ol,m);
141 return (struct java_util_Iterator*)oi;
144 /* Class: gnu/classpath/jdwp/VMVirtualMachine
145 * Method: getClassStatus
146 * Signature: (Ljava/lang/Class;)I
148 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassStatus(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
150 (*remotedbgjvmtienv)->GetClassStatus(remotedbgjvmtienv, (jclass) par1, &status);
155 * Class: gnu/classpath/jdwp/VMVirtualMachine
156 * Method: getAllClassMethods
157 * Signature: (Ljava/lang/Class;)[Lgnu/classpath/jdwp/VMMethod;
159 JNIEXPORT java_objectarray* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getAllClassMethods(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
160 log_text ("VMVirtualMachine_getAllClassMethods: IMPLEMENT ME !!!");
165 * Class: gnu/classpath/jdwp/VMVirtualMachine
166 * Method: getClassMethod
167 * Signature: (Ljava/lang/Class;J)Lgnu/classpath/jdwp/VMMethod;
169 JNIEXPORT struct gnu_classpath_jdwp_VMMethod* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getClassMethod(JNIEnv *env, jclass clazz, struct java_lang_Class* par1, s8 par2) {
170 log_text ("VMVirtualMachine_getAllClassMethod: IMPLEMENT ME !!!");
175 * Class: gnu/classpath/jdwp/VMVirtualMachine
177 * Signature: (Ljava/lang/Thread;II)Ljava/util/ArrayList;
179 JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrames(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, s4 par2, s4 par3) {
180 log_text ("VMVirtualMachine_getFrames - IMPLEMENT ME!!!");
181 /* jclass ec = (*env)->FindClass(env,"gnu/classpath/jdwp/JdwpInternalErrorException");
182 if (JVMTI_ERROR_NONE != (*remotedbgjvmtienv)->GetClassStatus(remotedbgjvmtienv, par1, &status))
183 env->ThrowNew(env,ec,"jvmti error occoured");*/
189 * Class: gnu/classpath/jdwp/VMVirtualMachine
191 * Signature: (Ljava/lang/Thread;Ljava/nio/ByteBuffer;)Lgnu/classpath/jdwp/VMFrame;
193 JNIEXPORT struct gnu_classpath_jdwp_VMFrame* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrame(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1, struct java_nio_ByteBuffer* par2) {
194 log_text ("VMVirtualMachine_getFrame - IMPLEMENT ME!!!");
200 * Class: gnu/classpath/jdwp/VMVirtualMachine
201 * Method: getFrameCount
202 * Signature: (Ljava/lang/Thread;)I
204 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getFrameCount(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
206 (*remotedbgjvmtienv)->GetFrameCount(remotedbgjvmtienv, (jthread)par1, &count);
212 * Class: gnu/classpath/jdwp/VMVirtualMachine
213 * Method: getThreadStatus
214 * Signature: (Ljava/lang/Thread;)I
216 JNIEXPORT s4 JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getThreadStatus(JNIEnv *env, jclass clazz, struct java_lang_Thread* par1) {
218 if (JVMTI_ERROR_NONE != (*remotedbgjvmtienv)->GetThreadState(remotedbgjvmtienv, (jthread)par1, &status))
220 if (status && JVMTI_THREAD_STATE_ALIVE) {
221 if (status && JVMTI_THREAD_STATE_WAITING) {
222 return 4; /* WAIT - see JdwpConstants */
224 if (status && JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) {
225 return 3; /* MONITOR - see JdwpConstants */
227 if (status && JVMTI_THREAD_STATE_SLEEPING) {
228 return 2; /* SLEEPING - see JdwpConstants */
230 return 1; /* RUNNING - see JdwpConstants */
232 return 0; /* ZOMBIE - see JdwpConstants */
233 return -1; /* some error */
238 * Class: gnu/classpath/jdwp/VMVirtualMachine
239 * Method: getLoadRequests
240 * Signature: (Ljava/lang/ClassLoader;)Ljava/util/ArrayList;
242 JNIEXPORT struct java_util_ArrayList* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getLoadRequests(JNIEnv *env, jclass clazz, struct java_lang_ClassLoader* par1) {
243 log_text ("VMVirtualMachine_getLoadRequests(");
249 * Class: gnu/classpath/jdwp/VMVirtualMachine
250 * Method: executeMethod
251 * Signature: (Ljava/lang/Object;Ljava/lang/Thread;Ljava/lang/Class;Ljava/lang/reflect/Method;[Ljava/lang/Object;Z)Lgnu/classpath/jdwp/util/MethodResult;
253 JNIEXPORT struct gnu_classpath_jdwp_util_MethodResult* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_executeMethod(JNIEnv *env, jclass clazz, struct java_lang_Object* par1, struct java_lang_Thread* par2, struct java_lang_Class* par3, struct java_lang_reflect_Method* par4, java_objectarray* par5, s4 par6) {
254 log_text ("VMVirtualMachine_executeMethod");
260 * Class: gnu/classpath/jdwp/VMVirtualMachine
261 * Method: getSourceFile
262 * Signature: (Ljava/lang/Class;)Ljava/lang/String;
264 JNIEXPORT struct java_lang_String* JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_getSourceFile(JNIEnv *env, jclass clazz, struct java_lang_Class* par1) {
268 (*remotedbgjvmtienv)->
269 GetSourceFileName(remotedbgjvmtienv, (jclass)par1, &srcname);
270 str = (*env)->NewString(env,(jchar*)srcname,(jsize)strlen(srcname));
272 return (struct java_lang_String*)str;
275 /* match JdwpConstants.EventKind to jvmtiEvent constants */
276 static jvmtiEvent EventKind2jvmtiEvent(jbyte kind){
278 case /* SINGLE_STEP */ 1: return JVMTI_EVENT_SINGLE_STEP;
279 case /* BREAKPOINT */ 2: return JVMTI_EVENT_BREAKPOINT;
280 case /* FRAME_POP */ 3: return JVMTI_EVENT_FRAME_POP;
281 case /* EXCEPTION */ 4: return JVMTI_EVENT_EXCEPTION;
282 case /* USER_DEFINED */ 5: return -1; /* can this be matched ? */
283 case /* THREAD_START */ 6: return JVMTI_EVENT_THREAD_START;
284 case /* THREAD_END */ 7: return JVMTI_EVENT_THREAD_END;
285 case /* CLASS_PREPARE */ 8: return JVMTI_EVENT_CLASS_PREPARE;
286 case /* CLASS_UNLOAD */ 9: return -1; /* can this be matched ? */
287 case /* CLASS_LOAD */ 10: return JVMTI_EVENT_CLASS_LOAD;
288 case /* FIELD_ACCESS */ 20: return JVMTI_EVENT_FIELD_ACCESS;
289 case /* FIELD_MODIFICATION */ 21: return JVMTI_EVENT_FIELD_MODIFICATION;
290 case /* EXCEPTION_CATCH */ 30: return JVMTI_EVENT_EXCEPTION_CATCH;
291 case /* METHOD_ENTRY */ 40: return JVMTI_EVENT_METHOD_ENTRY;
292 case /* METHOD_EXIT */ 41: return JVMTI_EVENT_METHOD_EXIT;
293 case /* VM_INIT */ 90: return JVMTI_EVENT_VM_INIT;
294 case /* VM_DEATH */ 99: return JVMTI_EVENT_VM_DEATH;
295 case /* VM_DISCONNECTED */ 100: return -1; /* can this be matched ? */
301 * Class: gnu/classpath/jdwp/VMVirtualMachine
302 * Method: registerEvent
303 * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V
305 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_registerEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) {
310 erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest");
312 kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
313 kind = (*env)->GetByteField(env, (jobject)par1, kindid);
315 (*remotedbgjvmtienv)->
316 SetEventNotificationMode(remotedbgjvmtienv, JVMTI_ENABLE,
317 EventKind2jvmtiEvent(kind), NULL);
319 /* todo: error handling, suspend policy */
324 * Class: gnu/classpath/jdwp/VMVirtualMachine
325 * Method: unregisterEvent
326 * Signature: (Lgnu/classpath/jdwp/event/EventRequest;)V
328 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_unregisterEvent(JNIEnv *env, jclass clazz, struct gnu_classpath_jdwp_event_EventRequest* par1) {
333 erc = (*env)->FindClass(env,"gnu.classpath.jdwp.event.EventRequest");
335 kindid = (*env)->GetFieldID(env, erc, "_kind", "B");
336 kind = (*env)->GetByteField(env, (jobject)par1, kindid);
338 (*remotedbgjvmtienv)->
339 SetEventNotificationMode(remotedbgjvmtienv, JVMTI_DISABLE,
340 EventKind2jvmtiEvent(kind), NULL);
342 /* todo: error handling, suspend policy */
347 * Class: gnu/classpath/jdwp/VMVirtualMachine
348 * Method: clearEvents
351 JNIEXPORT void JNICALL Java_gnu_classpath_jdwp_VMVirtualMachine_clearEvents(JNIEnv *env, jclass clazz, s4 par1) {
352 /* jvmti events are not saved */
353 log_text ("VMVirtualMachine_clearEvents IMPLEMENT ME!!!");
358 * These are local overrides for various environment variables in Emacs.
359 * Please do not remove this and leave it at the end of the file, where
360 * Emacs will automagically detect them.
361 * ---------------------------------------------------------------------
364 * indent-tabs-mode: t