Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/back/ThreadReferenceImpl.c
38765 views
/*1* Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#include "util.h"26#include "ThreadReferenceImpl.h"27#include "eventHandler.h"28#include "threadControl.h"29#include "inStream.h"30#include "outStream.h"31#include "FrameID.h"3233static jboolean34name(PacketInputStream *in, PacketOutputStream *out)35{36JNIEnv *env;37jthread thread;3839env = getEnv();4041thread = inStream_readThreadRef(env, in);42if (inStream_error(in)) {43return JNI_TRUE;44}4546if (threadControl_isDebugThread(thread)) {47outStream_setError(out, JDWP_ERROR(INVALID_THREAD));48return JNI_TRUE;49}5051WITH_LOCAL_REFS(env, 1) {5253jvmtiThreadInfo info;54jvmtiError error;5556(void)memset(&info, 0, sizeof(info));5758error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)59(gdata->jvmti, thread, &info);6061if (error != JVMTI_ERROR_NONE) {62outStream_setError(out, map2jdwpError(error));63} else {64(void)outStream_writeString(out, info.name);65}6667if ( info.name != NULL )68jvmtiDeallocate(info.name);6970} END_WITH_LOCAL_REFS(env);7172return JNI_TRUE;73}7475static jboolean76suspend(PacketInputStream *in, PacketOutputStream *out)77{78jvmtiError error;79jthread thread;8081thread = inStream_readThreadRef(getEnv(), in);82if (inStream_error(in)) {83return JNI_TRUE;84}8586if (threadControl_isDebugThread(thread)) {87outStream_setError(out, JDWP_ERROR(INVALID_THREAD));88return JNI_TRUE;89}90error = threadControl_suspendThread(thread, JNI_FALSE);91if (error != JVMTI_ERROR_NONE) {92outStream_setError(out, map2jdwpError(error));93}94return JNI_TRUE;95}9697static jboolean98resume(PacketInputStream *in, PacketOutputStream *out)99{100jvmtiError error;101jthread thread;102103thread = inStream_readThreadRef(getEnv(), in);104if (inStream_error(in)) {105return JNI_TRUE;106}107108if (threadControl_isDebugThread(thread)) {109outStream_setError(out, JDWP_ERROR(INVALID_THREAD));110return JNI_TRUE;111}112113/* true means it is okay to unblock the commandLoop thread */114error = threadControl_resumeThread(thread, JNI_TRUE);115if (error != JVMTI_ERROR_NONE) {116outStream_setError(out, map2jdwpError(error));117}118return JNI_TRUE;119}120121static jboolean122status(PacketInputStream *in, PacketOutputStream *out)123{124jdwpThreadStatus threadStatus;125jint statusFlags;126jvmtiError error;127jthread thread;128129thread = inStream_readThreadRef(getEnv(), in);130if (inStream_error(in)) {131return JNI_TRUE;132}133134if (threadControl_isDebugThread(thread)) {135outStream_setError(out, JDWP_ERROR(INVALID_THREAD));136return JNI_TRUE;137}138139error = threadControl_applicationThreadStatus(thread, &threadStatus,140&statusFlags);141if (error != JVMTI_ERROR_NONE) {142outStream_setError(out, map2jdwpError(error));143return JNI_TRUE;144}145(void)outStream_writeInt(out, threadStatus);146(void)outStream_writeInt(out, statusFlags);147return JNI_TRUE;148}149150static jboolean151threadGroup(PacketInputStream *in, PacketOutputStream *out)152{153JNIEnv *env;154jthread thread;155156env = getEnv();157158thread = inStream_readThreadRef(env, in);159if (inStream_error(in)) {160return JNI_TRUE;161}162163if (threadControl_isDebugThread(thread)) {164outStream_setError(out, JDWP_ERROR(INVALID_THREAD));165return JNI_TRUE;166}167168WITH_LOCAL_REFS(env, 1) {169170jvmtiThreadInfo info;171jvmtiError error;172173(void)memset(&info, 0, sizeof(info));174175error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)176(gdata->jvmti, thread, &info);177178if (error != JVMTI_ERROR_NONE) {179outStream_setError(out, map2jdwpError(error));180} else {181(void)outStream_writeObjectRef(env, out, info.thread_group);182}183184if ( info.name!=NULL )185jvmtiDeallocate(info.name);186187} END_WITH_LOCAL_REFS(env);188189return JNI_TRUE;190}191192static jboolean193validateSuspendedThread(PacketOutputStream *out, jthread thread)194{195jvmtiError error;196jint count;197198error = threadControl_suspendCount(thread, &count);199if (error != JVMTI_ERROR_NONE) {200outStream_setError(out, map2jdwpError(error));201return JNI_FALSE;202}203204if (count == 0) {205outStream_setError(out, JDWP_ERROR(THREAD_NOT_SUSPENDED));206return JNI_FALSE;207}208209return JNI_TRUE;210}211212static jboolean213frames(PacketInputStream *in, PacketOutputStream *out)214{215jvmtiError error;216FrameNumber fnum;217jint count;218JNIEnv *env;219jthread thread;220jint startIndex;221jint length;222223env = getEnv();224225thread = inStream_readThreadRef(env, in);226if (inStream_error(in)) {227return JNI_TRUE;228}229startIndex = inStream_readInt(in);230if (inStream_error(in)) {231return JNI_TRUE;232}233length = inStream_readInt(in);234if (inStream_error(in)) {235return JNI_TRUE;236}237238if (threadControl_isDebugThread(thread)) {239outStream_setError(out, JDWP_ERROR(INVALID_THREAD));240return JNI_TRUE;241}242243if (!validateSuspendedThread(out, thread)) {244return JNI_TRUE;245}246247error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)248(gdata->jvmti, thread, &count);249if (error != JVMTI_ERROR_NONE) {250outStream_setError(out, map2jdwpError(error));251return JNI_TRUE;252}253254if (length == -1) {255length = count - startIndex;256}257258if (length == 0) {259(void)outStream_writeInt(out, 0);260return JNI_TRUE;261}262263if ((startIndex < 0) || (startIndex > count - 1)) {264outStream_setError(out, JDWP_ERROR(INVALID_INDEX));265return JNI_TRUE;266}267268if ((length < 0) || (length + startIndex > count)) {269outStream_setError(out, JDWP_ERROR(INVALID_LENGTH));270return JNI_TRUE;271}272273(void)outStream_writeInt(out, length);274275for(fnum = startIndex ; fnum < startIndex+length ; fnum++ ) {276277WITH_LOCAL_REFS(env, 1) {278279jclass clazz;280jmethodID method;281jlocation location;282283/* Get location info */284error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameLocation)285(gdata->jvmti, thread, fnum, &method, &location);286if (error == JVMTI_ERROR_OPAQUE_FRAME) {287clazz = NULL;288location = -1L;289error = JVMTI_ERROR_NONE;290} else if ( error == JVMTI_ERROR_NONE ) {291error = methodClass(method, &clazz);292if ( error == JVMTI_ERROR_NONE ) {293FrameID frame;294frame = createFrameID(thread, fnum);295(void)outStream_writeFrameID(out, frame);296writeCodeLocation(out, clazz, method, location);297}298}299300} END_WITH_LOCAL_REFS(env);301302if (error != JVMTI_ERROR_NONE)303break;304305}306307if (error != JVMTI_ERROR_NONE) {308outStream_setError(out, map2jdwpError(error));309}310return JNI_TRUE;311}312313static jboolean314getFrameCount(PacketInputStream *in, PacketOutputStream *out)315{316jvmtiError error;317jint count;318jthread thread;319320thread = inStream_readThreadRef(getEnv(), in);321if (inStream_error(in)) {322return JNI_TRUE;323}324325if (threadControl_isDebugThread(thread)) {326outStream_setError(out, JDWP_ERROR(INVALID_THREAD));327return JNI_TRUE;328}329330if (!validateSuspendedThread(out, thread)) {331return JNI_TRUE;332}333334error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)335(gdata->jvmti, thread, &count);336if (error != JVMTI_ERROR_NONE) {337outStream_setError(out, map2jdwpError(error));338return JNI_TRUE;339}340(void)outStream_writeInt(out, count);341342return JNI_TRUE;343}344345static jboolean346ownedMonitors(PacketInputStream *in, PacketOutputStream *out)347{348JNIEnv *env;349jthread thread;350351env = getEnv();352353thread = inStream_readThreadRef(env, in);354if (inStream_error(in)) {355return JNI_TRUE;356}357358if (threadControl_isDebugThread(thread)) {359outStream_setError(out, JDWP_ERROR(INVALID_THREAD));360return JNI_TRUE;361}362363if (!validateSuspendedThread(out, thread)) {364return JNI_TRUE;365}366367WITH_LOCAL_REFS(env, 1) {368369jvmtiError error;370jint count = 0;371jobject *monitors = NULL;372373error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo)374(gdata->jvmti, thread, &count, &monitors);375if (error != JVMTI_ERROR_NONE) {376outStream_setError(out, map2jdwpError(error));377} else {378int i;379(void)outStream_writeInt(out, count);380for (i = 0; i < count; i++) {381jobject monitor = monitors[i];382(void)outStream_writeByte(out, specificTypeKey(env, monitor));383(void)outStream_writeObjectRef(env, out, monitor);384}385}386if (monitors != NULL)387jvmtiDeallocate(monitors);388389} END_WITH_LOCAL_REFS(env);390391return JNI_TRUE;392}393394static jboolean395currentContendedMonitor(PacketInputStream *in, PacketOutputStream *out)396{397JNIEnv *env;398jthread thread;399400env = getEnv();401402thread = inStream_readThreadRef(env, in);403if (inStream_error(in)) {404return JNI_TRUE;405}406407if (thread == NULL || threadControl_isDebugThread(thread)) {408outStream_setError(out, JDWP_ERROR(INVALID_THREAD));409return JNI_TRUE;410}411412if (!validateSuspendedThread(out, thread)) {413return JNI_TRUE;414}415416WITH_LOCAL_REFS(env, 1) {417418jobject monitor;419jvmtiError error;420421error = JVMTI_FUNC_PTR(gdata->jvmti,GetCurrentContendedMonitor)422(gdata->jvmti, thread, &monitor);423424if (error != JVMTI_ERROR_NONE) {425outStream_setError(out, map2jdwpError(error));426} else {427(void)outStream_writeByte(out, specificTypeKey(env, monitor));428(void)outStream_writeObjectRef(env, out, monitor);429}430431} END_WITH_LOCAL_REFS(env);432433return JNI_TRUE;434}435436static jboolean437stop(PacketInputStream *in, PacketOutputStream *out)438{439jvmtiError error;440jthread thread;441jobject throwable;442JNIEnv *env;443444env = getEnv();445thread = inStream_readThreadRef(env, in);446if (inStream_error(in)) {447return JNI_TRUE;448}449throwable = inStream_readObjectRef(env, in);450if (inStream_error(in)) {451return JNI_TRUE;452}453454if (threadControl_isDebugThread(thread)) {455outStream_setError(out, JDWP_ERROR(INVALID_THREAD));456return JNI_TRUE;457}458459error = threadControl_stop(thread, throwable);460if (error != JVMTI_ERROR_NONE) {461outStream_setError(out, map2jdwpError(error));462}463return JNI_TRUE;464}465466static jboolean467interrupt(PacketInputStream *in, PacketOutputStream *out)468{469jvmtiError error;470jthread thread;471472thread = inStream_readThreadRef(getEnv(), in);473if (inStream_error(in)) {474return JNI_TRUE;475}476477if (threadControl_isDebugThread(thread)) {478outStream_setError(out, JDWP_ERROR(INVALID_THREAD));479return JNI_TRUE;480}481482error = threadControl_interrupt(thread);483if (error != JVMTI_ERROR_NONE) {484outStream_setError(out, map2jdwpError(error));485}486return JNI_TRUE;487}488489static jboolean490suspendCount(PacketInputStream *in, PacketOutputStream *out)491{492jvmtiError error;493jint count;494jthread thread;495496thread = inStream_readThreadRef(getEnv(), in);497if (inStream_error(in)) {498return JNI_TRUE;499}500501if (threadControl_isDebugThread(thread)) {502outStream_setError(out, JDWP_ERROR(INVALID_THREAD));503return JNI_TRUE;504}505506error = threadControl_suspendCount(thread, &count);507if (error != JVMTI_ERROR_NONE) {508outStream_setError(out, map2jdwpError(error));509return JNI_TRUE;510}511512(void)outStream_writeInt(out, count);513return JNI_TRUE;514}515516static jboolean517ownedMonitorsWithStackDepth(PacketInputStream *in, PacketOutputStream *out)518{519JNIEnv *env;520jthread thread;521522thread = inStream_readThreadRef(getEnv(), in);523if (inStream_error(in)) {524return JNI_TRUE;525}526527if (thread == NULL || threadControl_isDebugThread(thread)) {528outStream_setError(out, JDWP_ERROR(INVALID_THREAD));529return JNI_TRUE;530}531532if (!validateSuspendedThread(out, thread)) {533return JNI_TRUE;534}535536env = getEnv();537538WITH_LOCAL_REFS(env, 1) {539540jvmtiError error = JVMTI_ERROR_NONE;541jint count = 0;542jvmtiMonitorStackDepthInfo *monitors=NULL;543544error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorStackDepthInfo)545(gdata->jvmti, thread, &count, &monitors);546547if (error != JVMTI_ERROR_NONE) {548outStream_setError(out, map2jdwpError(error));549} else {550int i;551(void)outStream_writeInt(out, count);552for (i = 0; i < count; i++) {553jobject monitor = monitors[i].monitor;554(void)outStream_writeByte(out, specificTypeKey(env, monitor));555(void)outStream_writeObjectRef(getEnv(), out, monitor);556(void)outStream_writeInt(out,monitors[i].stack_depth);557}558}559if (monitors != NULL) {560jvmtiDeallocate(monitors);561}562563} END_WITH_LOCAL_REFS(env);564565return JNI_TRUE;566}567568static jboolean569forceEarlyReturn(PacketInputStream *in, PacketOutputStream *out)570{571JNIEnv *env;572jthread thread;573jvalue value;574jbyte typeKey;575jvmtiError error;576577env = getEnv();578thread = inStream_readThreadRef(env, in);579if (inStream_error(in)) {580return JNI_TRUE;581}582583if (threadControl_isDebugThread(thread)) {584outStream_setError(out, JDWP_ERROR(INVALID_THREAD));585return JNI_TRUE;586}587588typeKey = inStream_readByte(in);589if (inStream_error(in)) {590return JNI_TRUE;591}592593if (isObjectTag(typeKey)) {594value.l = inStream_readObjectRef(env, in);595error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnObject)596(gdata->jvmti, thread, value.l);597} else {598switch (typeKey) {599case JDWP_TAG(VOID):600error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnVoid)601(gdata->jvmti, thread);602break;603case JDWP_TAG(BYTE):604value.b = inStream_readByte(in);605error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)606(gdata->jvmti, thread, value.b);607break;608609case JDWP_TAG(CHAR):610value.c = inStream_readChar(in);611error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)612(gdata->jvmti, thread, value.c);613break;614615case JDWP_TAG(FLOAT):616value.f = inStream_readFloat(in);617error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnFloat)618(gdata->jvmti, thread, value.f);619break;620621case JDWP_TAG(DOUBLE):622value.d = inStream_readDouble(in);623error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnDouble)624(gdata->jvmti, thread, value.d);625break;626627case JDWP_TAG(INT):628value.i = inStream_readInt(in);629error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)630(gdata->jvmti, thread, value.i);631break;632633case JDWP_TAG(LONG):634value.j = inStream_readLong(in);635error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnLong)636(gdata->jvmti, thread, value.j);637break;638639case JDWP_TAG(SHORT):640value.s = inStream_readShort(in);641error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)642(gdata->jvmti, thread, value.s);643break;644645case JDWP_TAG(BOOLEAN):646value.z = inStream_readBoolean(in);647error = JVMTI_FUNC_PTR(gdata->jvmti,ForceEarlyReturnInt)648(gdata->jvmti, thread, value.z);649break;650651default:652error = AGENT_ERROR_INVALID_TAG;653break;654}655}656{657jdwpError serror = map2jdwpError(error);658if (serror != JDWP_ERROR(NONE)) {659outStream_setError(out, serror);660}661}662return JNI_TRUE;663}664665666void *ThreadReference_Cmds[] = { (void *)14,667(void *)name,668(void *)suspend,669(void *)resume,670(void *)status,671(void *)threadGroup,672(void *)frames,673(void *)getFrameCount,674(void *)ownedMonitors,675(void *)currentContendedMonitor,676(void *)stop,677(void *)interrupt,678(void *)suspendCount,679(void *)ownedMonitorsWithStackDepth,680(void *)forceEarlyReturn681};682683684