|
1 /* |
|
2 * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. Sun designates this |
|
8 * particular file as subject to the "Classpath" exception as provided |
|
9 * by Sun in the LICENSE file that accompanied this code. |
|
10 * |
|
11 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
14 * version 2 for more details (a copy is included in the LICENSE file that |
|
15 * accompanied this code). |
|
16 * |
|
17 * You should have received a copy of the GNU General Public License version |
|
18 * 2 along with this work; if not, write to the Free Software Foundation, |
|
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
20 * |
|
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 * CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 * have any questions. |
|
24 */ |
|
25 |
|
26 #include "util.h" |
|
27 #include "ThreadReferenceImpl.h" |
|
28 #include "eventHandler.h" |
|
29 #include "threadControl.h" |
|
30 #include "inStream.h" |
|
31 #include "outStream.h" |
|
32 #include "FrameID.h" |
|
33 |
|
34 static jboolean |
|
35 name(PacketInputStream *in, PacketOutputStream *out) |
|
36 { |
|
37 JNIEnv *env; |
|
38 jthread thread; |
|
39 |
|
40 env = getEnv(); |
|
41 |
|
42 thread = inStream_readThreadRef(env, in); |
|
43 if (inStream_error(in)) { |
|
44 return JNI_TRUE; |
|
45 } |
|
46 |
|
47 if (threadControl_isDebugThread(thread)) { |
|
48 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
49 return JNI_TRUE; |
|
50 } |
|
51 |
|
52 WITH_LOCAL_REFS(env, 1) { |
|
53 |
|
54 jvmtiThreadInfo info; |
|
55 jvmtiError error; |
|
56 |
|
57 (void)memset(&info, 0, sizeof(info)); |
|
58 |
|
59 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo) |
|
60 (gdata->jvmti, thread, &info); |
|
61 |
|
62 if (error != JVMTI_ERROR_NONE) { |
|
63 outStream_setError(out, map2jdwpError(error)); |
|
64 } else { |
|
65 (void)outStream_writeString(out, info.name); |
|
66 } |
|
67 |
|
68 if ( info.name != NULL ) |
|
69 jvmtiDeallocate(info.name); |
|
70 |
|
71 } END_WITH_LOCAL_REFS(env); |
|
72 |
|
73 return JNI_TRUE; |
|
74 } |
|
75 |
|
76 static jboolean |
|
77 suspend(PacketInputStream *in, PacketOutputStream *out) |
|
78 { |
|
79 jvmtiError error; |
|
80 jthread thread; |
|
81 |
|
82 thread = inStream_readThreadRef(getEnv(), in); |
|
83 if (inStream_error(in)) { |
|
84 return JNI_TRUE; |
|
85 } |
|
86 |
|
87 if (threadControl_isDebugThread(thread)) { |
|
88 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
89 return JNI_TRUE; |
|
90 } |
|
91 error = threadControl_suspendThread(thread, JNI_FALSE); |
|
92 if (error != JVMTI_ERROR_NONE) { |
|
93 outStream_setError(out, map2jdwpError(error)); |
|
94 } |
|
95 return JNI_TRUE; |
|
96 } |
|
97 |
|
98 static jboolean |
|
99 resume(PacketInputStream *in, PacketOutputStream *out) |
|
100 { |
|
101 jvmtiError error; |
|
102 jthread thread; |
|
103 |
|
104 thread = inStream_readThreadRef(getEnv(), in); |
|
105 if (inStream_error(in)) { |
|
106 return JNI_TRUE; |
|
107 } |
|
108 |
|
109 if (threadControl_isDebugThread(thread)) { |
|
110 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
111 return JNI_TRUE; |
|
112 } |
|
113 |
|
114 /* true means it is okay to unblock the commandLoop thread */ |
|
115 error = threadControl_resumeThread(thread, JNI_TRUE); |
|
116 if (error != JVMTI_ERROR_NONE) { |
|
117 outStream_setError(out, map2jdwpError(error)); |
|
118 } |
|
119 return JNI_TRUE; |
|
120 } |
|
121 |
|
122 static jboolean |
|
123 status(PacketInputStream *in, PacketOutputStream *out) |
|
124 { |
|
125 jdwpThreadStatus threadStatus; |
|
126 jint statusFlags; |
|
127 jvmtiError error; |
|
128 jthread thread; |
|
129 |
|
130 thread = inStream_readThreadRef(getEnv(), in); |
|
131 if (inStream_error(in)) { |
|
132 return JNI_TRUE; |
|
133 } |
|
134 |
|
135 if (threadControl_isDebugThread(thread)) { |
|
136 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
137 return JNI_TRUE; |
|
138 } |
|
139 |
|
140 error = threadControl_applicationThreadStatus(thread, &threadStatus, |
|
141 &statusFlags); |
|
142 if (error != JVMTI_ERROR_NONE) { |
|
143 outStream_setError(out, map2jdwpError(error)); |
|
144 return JNI_TRUE; |
|
145 } |
|
146 (void)outStream_writeInt(out, threadStatus); |
|
147 (void)outStream_writeInt(out, statusFlags); |
|
148 return JNI_TRUE; |
|
149 } |
|
150 |
|
151 static jboolean |
|
152 threadGroup(PacketInputStream *in, PacketOutputStream *out) |
|
153 { |
|
154 JNIEnv *env; |
|
155 jthread thread; |
|
156 |
|
157 env = getEnv(); |
|
158 |
|
159 thread = inStream_readThreadRef(env, in); |
|
160 if (inStream_error(in)) { |
|
161 return JNI_TRUE; |
|
162 } |
|
163 |
|
164 if (threadControl_isDebugThread(thread)) { |
|
165 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
166 return JNI_TRUE; |
|
167 } |
|
168 |
|
169 WITH_LOCAL_REFS(env, 1) { |
|
170 |
|
171 jvmtiThreadInfo info; |
|
172 jvmtiError error; |
|
173 |
|
174 (void)memset(&info, 0, sizeof(info)); |
|
175 |
|
176 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo) |
|
177 (gdata->jvmti, thread, &info); |
|
178 |
|
179 if (error != JVMTI_ERROR_NONE) { |
|
180 outStream_setError(out, map2jdwpError(error)); |
|
181 } else { |
|
182 (void)outStream_writeObjectRef(env, out, info.thread_group); |
|
183 } |
|
184 |
|
185 if ( info.name!=NULL ) |
|
186 jvmtiDeallocate(info.name); |
|
187 |
|
188 } END_WITH_LOCAL_REFS(env); |
|
189 |
|
190 return JNI_TRUE; |
|
191 } |
|
192 |
|
193 static jboolean |
|
194 validateSuspendedThread(PacketOutputStream *out, jthread thread) |
|
195 { |
|
196 jvmtiError error; |
|
197 jint count; |
|
198 |
|
199 error = threadControl_suspendCount(thread, &count); |
|
200 if (error != JVMTI_ERROR_NONE) { |
|
201 outStream_setError(out, map2jdwpError(error)); |
|
202 return JNI_FALSE; |
|
203 } |
|
204 |
|
205 if (count == 0) { |
|
206 outStream_setError(out, JDWP_ERROR(THREAD_NOT_SUSPENDED)); |
|
207 return JNI_FALSE; |
|
208 } |
|
209 |
|
210 return JNI_TRUE; |
|
211 } |
|
212 |
|
213 static jboolean |
|
214 frames(PacketInputStream *in, PacketOutputStream *out) |
|
215 { |
|
216 jvmtiError error; |
|
217 FrameNumber fnum; |
|
218 jint count; |
|
219 JNIEnv *env; |
|
220 jthread thread; |
|
221 jint startIndex; |
|
222 jint length; |
|
223 |
|
224 env = getEnv(); |
|
225 |
|
226 thread = inStream_readThreadRef(env, in); |
|
227 if (inStream_error(in)) { |
|
228 return JNI_TRUE; |
|
229 } |
|
230 startIndex = inStream_readInt(in); |
|
231 if (inStream_error(in)) { |
|
232 return JNI_TRUE; |
|
233 } |
|
234 length = inStream_readInt(in); |
|
235 if (inStream_error(in)) { |
|
236 return JNI_TRUE; |
|
237 } |
|
238 |
|
239 if (threadControl_isDebugThread(thread)) { |
|
240 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
241 return JNI_TRUE; |
|
242 } |
|
243 |
|
244 if (!validateSuspendedThread(out, thread)) { |
|
245 return JNI_TRUE; |
|
246 } |
|
247 |
|
248 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount) |
|
249 (gdata->jvmti, thread, &count); |
|
250 if (error != JVMTI_ERROR_NONE) { |
|
251 outStream_setError(out, map2jdwpError(error)); |
|
252 return JNI_TRUE; |
|
253 } |
|
254 |
|
255 if (length == -1) { |
|
256 length = count - startIndex; |
|
257 } |
|
258 |
|
259 if (length == 0) { |
|
260 (void)outStream_writeInt(out, 0); |
|
261 return JNI_TRUE; |
|
262 } |
|
263 |
|
264 if ((startIndex < 0) || (startIndex > count - 1)) { |
|
265 outStream_setError(out, JDWP_ERROR(INVALID_INDEX)); |
|
266 return JNI_TRUE; |
|
267 } |
|
268 |
|
269 if ((length < 0) || (length + startIndex > count)) { |
|
270 outStream_setError(out, JDWP_ERROR(INVALID_LENGTH)); |
|
271 return JNI_TRUE; |
|
272 } |
|
273 |
|
274 (void)outStream_writeInt(out, length); |
|
275 |
|
276 for(fnum = startIndex ; fnum < startIndex+length ; fnum++ ) { |
|
277 |
|
278 WITH_LOCAL_REFS(env, 1) { |
|
279 |
|
280 jclass clazz; |
|
281 jmethodID method; |
|
282 jlocation location; |
|
283 |
|
284 /* Get location info */ |
|
285 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation) |
|
286 (gdata->jvmti, thread, fnum, &method, &location); |
|
287 if (error == JVMTI_ERROR_OPAQUE_FRAME) { |
|
288 clazz = NULL; |
|
289 location = -1L; |
|
290 error = JVMTI_ERROR_NONE; |
|
291 } else if ( error == JVMTI_ERROR_NONE ) { |
|
292 error = methodClass(method, &clazz); |
|
293 if ( error == JVMTI_ERROR_NONE ) { |
|
294 FrameID frame; |
|
295 frame = createFrameID(thread, fnum); |
|
296 (void)outStream_writeFrameID(out, frame); |
|
297 writeCodeLocation(out, clazz, method, location); |
|
298 } |
|
299 } |
|
300 |
|
301 } END_WITH_LOCAL_REFS(env); |
|
302 |
|
303 if (error != JVMTI_ERROR_NONE) |
|
304 break; |
|
305 |
|
306 } |
|
307 |
|
308 if (error != JVMTI_ERROR_NONE) { |
|
309 outStream_setError(out, map2jdwpError(error)); |
|
310 } |
|
311 return JNI_TRUE; |
|
312 } |
|
313 |
|
314 static jboolean |
|
315 getFrameCount(PacketInputStream *in, PacketOutputStream *out) |
|
316 { |
|
317 jvmtiError error; |
|
318 jint count; |
|
319 jthread thread; |
|
320 |
|
321 thread = inStream_readThreadRef(getEnv(), in); |
|
322 if (inStream_error(in)) { |
|
323 return JNI_TRUE; |
|
324 } |
|
325 |
|
326 if (threadControl_isDebugThread(thread)) { |
|
327 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
328 return JNI_TRUE; |
|
329 } |
|
330 |
|
331 if (!validateSuspendedThread(out, thread)) { |
|
332 return JNI_TRUE; |
|
333 } |
|
334 |
|
335 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount) |
|
336 (gdata->jvmti, thread, &count); |
|
337 if (error != JVMTI_ERROR_NONE) { |
|
338 outStream_setError(out, map2jdwpError(error)); |
|
339 return JNI_TRUE; |
|
340 } |
|
341 (void)outStream_writeInt(out, count); |
|
342 |
|
343 return JNI_TRUE; |
|
344 } |
|
345 |
|
346 static jboolean |
|
347 ownedMonitors(PacketInputStream *in, PacketOutputStream *out) |
|
348 { |
|
349 JNIEnv *env; |
|
350 jthread thread; |
|
351 |
|
352 env = getEnv(); |
|
353 |
|
354 thread = inStream_readThreadRef(env, in); |
|
355 if (inStream_error(in)) { |
|
356 return JNI_TRUE; |
|
357 } |
|
358 |
|
359 if (threadControl_isDebugThread(thread)) { |
|
360 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
361 return JNI_TRUE; |
|
362 } |
|
363 |
|
364 if (!validateSuspendedThread(out, thread)) { |
|
365 return JNI_TRUE; |
|
366 } |
|
367 |
|
368 WITH_LOCAL_REFS(env, 1) { |
|
369 |
|
370 jvmtiError error; |
|
371 jint count = 0; |
|
372 jobject *monitors = NULL; |
|
373 |
|
374 error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo) |
|
375 (gdata->jvmti, thread, &count, &monitors); |
|
376 if (error != JVMTI_ERROR_NONE) { |
|
377 outStream_setError(out, map2jdwpError(error)); |
|
378 } else { |
|
379 int i; |
|
380 (void)outStream_writeInt(out, count); |
|
381 for (i = 0; i < count; i++) { |
|
382 jobject monitor = monitors[i]; |
|
383 (void)outStream_writeByte(out, specificTypeKey(env, monitor)); |
|
384 (void)outStream_writeObjectRef(env, out, monitor); |
|
385 } |
|
386 } |
|
387 if (monitors != NULL) |
|
388 jvmtiDeallocate(monitors); |
|
389 |
|
390 } END_WITH_LOCAL_REFS(env); |
|
391 |
|
392 return JNI_TRUE; |
|
393 } |
|
394 |
|
395 static jboolean |
|
396 currentContendedMonitor(PacketInputStream *in, PacketOutputStream *out) |
|
397 { |
|
398 JNIEnv *env; |
|
399 jthread thread; |
|
400 |
|
401 env = getEnv(); |
|
402 |
|
403 thread = inStream_readThreadRef(env, in); |
|
404 if (inStream_error(in)) { |
|
405 return JNI_TRUE; |
|
406 } |
|
407 |
|
408 if (thread == NULL || threadControl_isDebugThread(thread)) { |
|
409 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
410 return JNI_TRUE; |
|
411 } |
|
412 |
|
413 if (!validateSuspendedThread(out, thread)) { |
|
414 return JNI_TRUE; |
|
415 } |
|
416 |
|
417 WITH_LOCAL_REFS(env, 1) { |
|
418 |
|
419 jobject monitor; |
|
420 jvmtiError error; |
|
421 |
|
422 error = JVMTI_FUNC_PTR(gdata->jvmti,GetCurrentContendedMonitor) |
|
423 (gdata->jvmti, thread, &monitor); |
|
424 |
|
425 if (error != JVMTI_ERROR_NONE) { |
|
426 outStream_setError(out, map2jdwpError(error)); |
|
427 } else { |
|
428 (void)outStream_writeByte(out, specificTypeKey(env, monitor)); |
|
429 (void)outStream_writeObjectRef(env, out, monitor); |
|
430 } |
|
431 |
|
432 } END_WITH_LOCAL_REFS(env); |
|
433 |
|
434 return JNI_TRUE; |
|
435 } |
|
436 |
|
437 static jboolean |
|
438 stop(PacketInputStream *in, PacketOutputStream *out) |
|
439 { |
|
440 jvmtiError error; |
|
441 jthread thread; |
|
442 jobject throwable; |
|
443 JNIEnv *env; |
|
444 |
|
445 env = getEnv(); |
|
446 thread = inStream_readThreadRef(env, in); |
|
447 if (inStream_error(in)) { |
|
448 return JNI_TRUE; |
|
449 } |
|
450 throwable = inStream_readObjectRef(env, in); |
|
451 if (inStream_error(in)) { |
|
452 return JNI_TRUE; |
|
453 } |
|
454 |
|
455 if (threadControl_isDebugThread(thread)) { |
|
456 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
457 return JNI_TRUE; |
|
458 } |
|
459 |
|
460 error = threadControl_stop(thread, throwable); |
|
461 if (error != JVMTI_ERROR_NONE) { |
|
462 outStream_setError(out, map2jdwpError(error)); |
|
463 } |
|
464 return JNI_TRUE; |
|
465 } |
|
466 |
|
467 static jboolean |
|
468 interrupt(PacketInputStream *in, PacketOutputStream *out) |
|
469 { |
|
470 jvmtiError error; |
|
471 jthread thread; |
|
472 |
|
473 thread = inStream_readThreadRef(getEnv(), in); |
|
474 if (inStream_error(in)) { |
|
475 return JNI_TRUE; |
|
476 } |
|
477 |
|
478 if (threadControl_isDebugThread(thread)) { |
|
479 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
480 return JNI_TRUE; |
|
481 } |
|
482 |
|
483 error = threadControl_interrupt(thread); |
|
484 if (error != JVMTI_ERROR_NONE) { |
|
485 outStream_setError(out, map2jdwpError(error)); |
|
486 } |
|
487 return JNI_TRUE; |
|
488 } |
|
489 |
|
490 static jboolean |
|
491 suspendCount(PacketInputStream *in, PacketOutputStream *out) |
|
492 { |
|
493 jvmtiError error; |
|
494 jint count; |
|
495 jthread thread; |
|
496 |
|
497 thread = inStream_readThreadRef(getEnv(), in); |
|
498 if (inStream_error(in)) { |
|
499 return JNI_TRUE; |
|
500 } |
|
501 |
|
502 if (threadControl_isDebugThread(thread)) { |
|
503 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
504 return JNI_TRUE; |
|
505 } |
|
506 |
|
507 error = threadControl_suspendCount(thread, &count); |
|
508 if (error != JVMTI_ERROR_NONE) { |
|
509 outStream_setError(out, map2jdwpError(error)); |
|
510 return JNI_TRUE; |
|
511 } |
|
512 |
|
513 (void)outStream_writeInt(out, count); |
|
514 return JNI_TRUE; |
|
515 } |
|
516 |
|
517 static jboolean |
|
518 ownedMonitorsWithStackDepth(PacketInputStream *in, PacketOutputStream *out) |
|
519 { |
|
520 JNIEnv *env; |
|
521 jthread thread; |
|
522 |
|
523 thread = inStream_readThreadRef(getEnv(), in); |
|
524 if (inStream_error(in)) { |
|
525 return JNI_TRUE; |
|
526 } |
|
527 |
|
528 if (thread == NULL || threadControl_isDebugThread(thread)) { |
|
529 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
530 return JNI_TRUE; |
|
531 } |
|
532 |
|
533 if (!validateSuspendedThread(out, thread)) { |
|
534 return JNI_TRUE; |
|
535 } |
|
536 |
|
537 env = getEnv(); |
|
538 |
|
539 WITH_LOCAL_REFS(env, 1) { |
|
540 |
|
541 jvmtiError error = JVMTI_ERROR_NONE; |
|
542 jint count = 0; |
|
543 jint depth; |
|
544 jvmtiMonitorStackDepthInfo *monitors=NULL; |
|
545 |
|
546 error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorStackDepthInfo) |
|
547 (gdata->jvmti, thread, &count, &monitors); |
|
548 |
|
549 if (error != JVMTI_ERROR_NONE) { |
|
550 outStream_setError(out, map2jdwpError(error)); |
|
551 } else { |
|
552 int i; |
|
553 (void)outStream_writeInt(out, count); |
|
554 for (i = 0; i < count; i++) { |
|
555 jobject monitor = monitors[i].monitor; |
|
556 (void)outStream_writeByte(out, specificTypeKey(env, monitor)); |
|
557 (void)outStream_writeObjectRef(getEnv(), out, monitor); |
|
558 (void)outStream_writeInt(out,monitors[i].stack_depth); |
|
559 } |
|
560 } |
|
561 if (monitors != NULL) { |
|
562 jvmtiDeallocate(monitors); |
|
563 } |
|
564 |
|
565 } END_WITH_LOCAL_REFS(env); |
|
566 |
|
567 return JNI_TRUE; |
|
568 } |
|
569 |
|
570 static jboolean |
|
571 forceEarlyReturn(PacketInputStream *in, PacketOutputStream *out) |
|
572 { |
|
573 JNIEnv *env; |
|
574 jthread thread; |
|
575 jvalue value; |
|
576 jbyte typeKey; |
|
577 jvmtiError error; |
|
578 |
|
579 env = getEnv(); |
|
580 thread = inStream_readThreadRef(env, in); |
|
581 if (inStream_error(in)) { |
|
582 return JNI_TRUE; |
|
583 } |
|
584 |
|
585 if (threadControl_isDebugThread(thread)) { |
|
586 outStream_setError(out, JDWP_ERROR(INVALID_THREAD)); |
|
587 return JNI_TRUE; |
|
588 } |
|
589 |
|
590 typeKey = inStream_readByte(in); |
|
591 if (inStream_error(in)) { |
|
592 return JNI_TRUE; |
|
593 } |
|
594 |
|
595 if (isObjectTag(typeKey)) { |
|
596 value.l = inStream_readObjectRef(env, in); |
|
597 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnObject) |
|
598 (gdata->jvmti, thread, value.l); |
|
599 } else { |
|
600 switch (typeKey) { |
|
601 case JDWP_TAG(VOID): |
|
602 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnVoid) |
|
603 (gdata->jvmti, thread); |
|
604 break; |
|
605 case JDWP_TAG(BYTE): |
|
606 value.b = inStream_readByte(in); |
|
607 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt) |
|
608 (gdata->jvmti, thread, value.b); |
|
609 break; |
|
610 |
|
611 case JDWP_TAG(CHAR): |
|
612 value.c = inStream_readChar(in); |
|
613 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt) |
|
614 (gdata->jvmti, thread, value.c); |
|
615 break; |
|
616 |
|
617 case JDWP_TAG(FLOAT): |
|
618 value.f = inStream_readFloat(in); |
|
619 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnFloat) |
|
620 (gdata->jvmti, thread, value.f); |
|
621 break; |
|
622 |
|
623 case JDWP_TAG(DOUBLE): |
|
624 value.d = inStream_readDouble(in); |
|
625 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnDouble) |
|
626 (gdata->jvmti, thread, value.d); |
|
627 break; |
|
628 |
|
629 case JDWP_TAG(INT): |
|
630 value.i = inStream_readInt(in); |
|
631 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt) |
|
632 (gdata->jvmti, thread, value.i); |
|
633 break; |
|
634 |
|
635 case JDWP_TAG(LONG): |
|
636 value.j = inStream_readLong(in); |
|
637 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnLong) |
|
638 (gdata->jvmti, thread, value.j); |
|
639 break; |
|
640 |
|
641 case JDWP_TAG(SHORT): |
|
642 value.s = inStream_readShort(in); |
|
643 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt) |
|
644 (gdata->jvmti, thread, value.s); |
|
645 break; |
|
646 |
|
647 case JDWP_TAG(BOOLEAN): |
|
648 value.z = inStream_readBoolean(in); |
|
649 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt) |
|
650 (gdata->jvmti, thread, value.z); |
|
651 break; |
|
652 |
|
653 default: |
|
654 error = AGENT_ERROR_INVALID_TAG; |
|
655 break; |
|
656 } |
|
657 } |
|
658 { |
|
659 jdwpError serror = map2jdwpError(error); |
|
660 if (serror != JDWP_ERROR(NONE)) { |
|
661 outStream_setError(out, serror); |
|
662 } |
|
663 } |
|
664 return JNI_TRUE; |
|
665 } |
|
666 |
|
667 |
|
668 void *ThreadReference_Cmds[] = { (void *)14, |
|
669 (void *)name, |
|
670 (void *)suspend, |
|
671 (void *)resume, |
|
672 (void *)status, |
|
673 (void *)threadGroup, |
|
674 (void *)frames, |
|
675 (void *)getFrameCount, |
|
676 (void *)ownedMonitors, |
|
677 (void *)currentContendedMonitor, |
|
678 (void *)stop, |
|
679 (void *)interrupt, |
|
680 (void *)suspendCount, |
|
681 (void *)ownedMonitorsWithStackDepth, |
|
682 (void *)forceEarlyReturn |
|
683 }; |