1 | /*
|
---|
2 | * Copyright (c) 1998, 2008, Oracle and/or its affiliates. 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. Oracle designates this
|
---|
8 | * particular file as subject to the "Classpath" exception as provided
|
---|
9 | * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
---|
22 | * or visit www.oracle.com if you need additional information or have any
|
---|
23 | * 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 | jvmtiMonitorStackDepthInfo *monitors=NULL;
|
---|
544 |
|
---|
545 | error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorStackDepthInfo)
|
---|
546 | (gdata->jvmti, thread, &count, &monitors);
|
---|
547 |
|
---|
548 | if (error != JVMTI_ERROR_NONE) {
|
---|
549 | outStream_setError(out, map2jdwpError(error));
|
---|
550 | } else {
|
---|
551 | int i;
|
---|
552 | (void)outStream_writeInt(out, count);
|
---|
553 | for (i = 0; i < count; i++) {
|
---|
554 | jobject monitor = monitors[i].monitor;
|
---|
555 | (void)outStream_writeByte(out, specificTypeKey(env, monitor));
|
---|
556 | (void)outStream_writeObjectRef(getEnv(), out, monitor);
|
---|
557 | (void)outStream_writeInt(out,monitors[i].stack_depth);
|
---|
558 | }
|
---|
559 | }
|
---|
560 | if (monitors != NULL) {
|
---|
561 | jvmtiDeallocate(monitors);
|
---|
562 | }
|
---|
563 |
|
---|
564 | } END_WITH_LOCAL_REFS(env);
|
---|
565 |
|
---|
566 | return JNI_TRUE;
|
---|
567 | }
|
---|
568 |
|
---|
569 | static jboolean
|
---|
570 | forceEarlyReturn(PacketInputStream *in, PacketOutputStream *out)
|
---|
571 | {
|
---|
572 | JNIEnv *env;
|
---|
573 | jthread thread;
|
---|
574 | jvalue value;
|
---|
575 | jbyte typeKey;
|
---|
576 | jvmtiError error;
|
---|
577 |
|
---|
578 | env = getEnv();
|
---|
579 | thread = inStream_readThreadRef(env, in);
|
---|
580 | if (inStream_error(in)) {
|
---|
581 | return JNI_TRUE;
|
---|
582 | }
|
---|
583 |
|
---|
584 | if (threadControl_isDebugThread(thread)) {
|
---|
585 | outStream_setError(out, JDWP_ERROR(INVALID_THREAD));
|
---|
586 | return JNI_TRUE;
|
---|
587 | }
|
---|
588 |
|
---|
589 | typeKey = inStream_readByte(in);
|
---|
590 | if (inStream_error(in)) {
|
---|
591 | return JNI_TRUE;
|
---|
592 | }
|
---|
593 |
|
---|
594 | if (isObjectTag(typeKey)) {
|
---|
595 | value.l = inStream_readObjectRef(env, in);
|
---|
596 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnObject)
|
---|
597 | (gdata->jvmti, thread, value.l);
|
---|
598 | } else {
|
---|
599 | switch (typeKey) {
|
---|
600 | case JDWP_TAG(VOID):
|
---|
601 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnVoid)
|
---|
602 | (gdata->jvmti, thread);
|
---|
603 | break;
|
---|
604 | case JDWP_TAG(BYTE):
|
---|
605 | value.b = inStream_readByte(in);
|
---|
606 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
|
---|
607 | (gdata->jvmti, thread, value.b);
|
---|
608 | break;
|
---|
609 |
|
---|
610 | case JDWP_TAG(CHAR):
|
---|
611 | value.c = inStream_readChar(in);
|
---|
612 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
|
---|
613 | (gdata->jvmti, thread, value.c);
|
---|
614 | break;
|
---|
615 |
|
---|
616 | case JDWP_TAG(FLOAT):
|
---|
617 | value.f = inStream_readFloat(in);
|
---|
618 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnFloat)
|
---|
619 | (gdata->jvmti, thread, value.f);
|
---|
620 | break;
|
---|
621 |
|
---|
622 | case JDWP_TAG(DOUBLE):
|
---|
623 | value.d = inStream_readDouble(in);
|
---|
624 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnDouble)
|
---|
625 | (gdata->jvmti, thread, value.d);
|
---|
626 | break;
|
---|
627 |
|
---|
628 | case JDWP_TAG(INT):
|
---|
629 | value.i = inStream_readInt(in);
|
---|
630 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
|
---|
631 | (gdata->jvmti, thread, value.i);
|
---|
632 | break;
|
---|
633 |
|
---|
634 | case JDWP_TAG(LONG):
|
---|
635 | value.j = inStream_readLong(in);
|
---|
636 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnLong)
|
---|
637 | (gdata->jvmti, thread, value.j);
|
---|
638 | break;
|
---|
639 |
|
---|
640 | case JDWP_TAG(SHORT):
|
---|
641 | value.s = inStream_readShort(in);
|
---|
642 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
|
---|
643 | (gdata->jvmti, thread, value.s);
|
---|
644 | break;
|
---|
645 |
|
---|
646 | case JDWP_TAG(BOOLEAN):
|
---|
647 | value.z = inStream_readBoolean(in);
|
---|
648 | error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)
|
---|
649 | (gdata->jvmti, thread, value.z);
|
---|
650 | break;
|
---|
651 |
|
---|
652 | default:
|
---|
653 | error = AGENT_ERROR_INVALID_TAG;
|
---|
654 | break;
|
---|
655 | }
|
---|
656 | }
|
---|
657 | {
|
---|
658 | jdwpError serror = map2jdwpError(error);
|
---|
659 | if (serror != JDWP_ERROR(NONE)) {
|
---|
660 | outStream_setError(out, serror);
|
---|
661 | }
|
---|
662 | }
|
---|
663 | return JNI_TRUE;
|
---|
664 | }
|
---|
665 |
|
---|
666 |
|
---|
667 | void *ThreadReference_Cmds[] = { (void *)14,
|
---|
668 | (void *)name,
|
---|
669 | (void *)suspend,
|
---|
670 | (void *)resume,
|
---|
671 | (void *)status,
|
---|
672 | (void *)threadGroup,
|
---|
673 | (void *)frames,
|
---|
674 | (void *)getFrameCount,
|
---|
675 | (void *)ownedMonitors,
|
---|
676 | (void *)currentContendedMonitor,
|
---|
677 | (void *)stop,
|
---|
678 | (void *)interrupt,
|
---|
679 | (void *)suspendCount,
|
---|
680 | (void *)ownedMonitorsWithStackDepth,
|
---|
681 | (void *)forceEarlyReturn
|
---|
682 | };
|
---|