1 /*
2 * Copyright (c) 1998, 2007, 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
326 return JVMTI_ERROR_NONE;
327 }
328
329 void
330 invoker_enableInvokeRequests(jthread thread)
331 {
332 InvokeRequest *request;
333
334 JDI_ASSERT(thread);
335
336 debugMonitorEnter(invokerLock);
337 request = threadControl_getInvokeRequest(thread);
338 if (request == NULL) {
339 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
340 }
341
342 request->available = JNI_TRUE;
343 debugMonitorExit(invokerLock);
344 }
345
346 jvmtiError
347 invoker_requestInvoke(jbyte invokeType, jbyte options, jint id,
348 jthread thread, jclass clazz, jmethodID method,
349 jobject instance,
350 jvalue *arguments, jint argumentCount)
351 {
352 JNIEnv *env = getEnv();
353 InvokeRequest *request;
354 jvmtiError error = JVMTI_ERROR_NONE;
355
356 debugMonitorEnter(invokerLock);
357 request = threadControl_getInvokeRequest(thread);
358 if (request != NULL) {
359 error = fillInvokeRequest(env, request, invokeType, options, id,
360 thread, clazz, method, instance,
361 arguments, argumentCount);
362 }
363 debugMonitorExit(invokerLock);
364
365 if (error == JVMTI_ERROR_NONE) {
366 if (options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED) ) {
367 /* true means it is okay to unblock the commandLoop thread */
368 (void)threadControl_resumeThread(thread, JNI_TRUE);
369 } else {
370 (void)threadControl_resumeAll();
371 }
372 }
373
374 return error;
|
1 /*
2 * Copyright (c) 1998, 2016, 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
326 return JVMTI_ERROR_NONE;
327 }
328
329 void
330 invoker_enableInvokeRequests(jthread thread)
331 {
332 InvokeRequest *request;
333
334 JDI_ASSERT(thread);
335
336 debugMonitorEnter(invokerLock);
337 request = threadControl_getInvokeRequest(thread);
338 if (request == NULL) {
339 EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request");
340 }
341
342 request->available = JNI_TRUE;
343 debugMonitorExit(invokerLock);
344 }
345
346 /*
347 * Check that method is in the specified clazz or one of its super classes.
348 * We have to enforce this check at the JDWP layer because the JNI layer
349 * has different requirements.
350 */
351 static jvmtiError check_methodClass(JNIEnv *env, jclass clazz, jmethodID method)
352 {
353 jclass containing_class = NULL;
354 jvmtiError error;
355
356 error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
357 (gdata->jvmti, method, &containing_class);
358 if (error != JVMTI_ERROR_NONE) {
359 return JVMTI_ERROR_NONE; /* Bad jmethodID ? This will be handled elsewhere */
360 }
361
362 if (JNI_FUNC_PTR(env,IsSameObject)(env, clazz, containing_class)) {
363 return JVMTI_ERROR_NONE;
364 }
365
366 // If not the same class then check that containing_class is a superclass of
367 // clazz (not a superinterface).
368 if (JNI_FUNC_PTR(env,IsAssignableFrom)(env, clazz, containing_class) &&
369 referenceTypeTag(containing_class) != JDWP_TYPE_TAG(INTERFACE)) {
370 return JVMTI_ERROR_NONE;
371 }
372 return JVMTI_ERROR_INVALID_METHODID;
373 }
374
375 jvmtiError
376 invoker_requestInvoke(jbyte invokeType, jbyte options, jint id,
377 jthread thread, jclass clazz, jmethodID method,
378 jobject instance,
379 jvalue *arguments, jint argumentCount)
380 {
381 JNIEnv *env = getEnv();
382 InvokeRequest *request;
383 jvmtiError error = JVMTI_ERROR_NONE;
384
385 if (invokeType == INVOKE_STATIC) {
386 error = check_methodClass(env, clazz, method);
387 if (error != JVMTI_ERROR_NONE) {
388 return error;
389 }
390 }
391
392 debugMonitorEnter(invokerLock);
393 request = threadControl_getInvokeRequest(thread);
394 if (request != NULL) {
395 error = fillInvokeRequest(env, request, invokeType, options, id,
396 thread, clazz, method, instance,
397 arguments, argumentCount);
398 }
399 debugMonitorExit(invokerLock);
400
401 if (error == JVMTI_ERROR_NONE) {
402 if (options & JDWP_INVOKE_OPTIONS(SINGLE_THREADED) ) {
403 /* true means it is okay to unblock the commandLoop thread */
404 (void)threadControl_resumeThread(thread, JNI_TRUE);
405 } else {
406 (void)threadControl_resumeAll();
407 }
408 }
409
410 return error;
|