00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00027 #include "referencetypecmdset.h"
00028 #include "virtualmachinecmdset.h"
00029 namespace inspectorj {
00030 namespace agent {
00031 namespace commandset {
00032
00033 using namespace inspectorj::jdwp;
00034
00038 ReferenceTypeCmdSet::ReferenceTypeCmdSet(JavaVM *vm, JNIEnv *env, jvmtiEnv *jvmti)
00039 {
00040 this->vm = vm;
00041 this->env = env;
00042 this->jvmti = jvmti;
00043 }
00044
00048 ReferenceTypeCmdSet::~ReferenceTypeCmdSet()
00049 {
00050 }
00051
00052
00058 void ReferenceTypeCmdSet::process(JDWPCommand* cmd, boost::function< void (JDWPReply*) > cbk)
00059 {
00060 int jdwpCmd = static_cast<int>(cmd->getCmd());
00061 switch (jdwpCmd) {
00062 case REF_TYPE_CMD_FIELDS : getFields(cmd, cbk); break;
00063 case REF_TYPE_CMD_METHODS : getMethods(cmd, cbk); break;
00064 default : sendNotImplementedReply(cmd, cbk); break;
00065 }
00066 }
00067
00079 void ReferenceTypeCmdSet::getFields(JDWPCommand* cmd, boost::function< void (JDWPReply*) > cbk)
00080 {
00081 JDWPReply *reply = getJDWPReply(cmd);
00082 qint64 refid;
00083 *cmd >> refid;
00084 jint fieldCnt;
00085 jfieldID *fieldIds;
00086 jvmtiError error;
00087 if (JDWPCommandSet::getClassMap().contains(refid)) {
00088 jclass klass = JDWPCommandSet::getClassMap().value(refid);
00089 error = jvmti->GetClassFields(klass, &fieldCnt, &fieldIds);
00090 if (error) {
00091 reply->setErrorCode((short) error);
00092 cbk(reply);
00093 return;
00094 }
00095 *reply << fieldCnt;
00096 for (int i = 0; i < fieldCnt; i++) {
00097 char *fieldName;
00098 char *fieldSignature;
00099 char *generic;
00100 error = jvmti->GetFieldName(
00101 klass,
00102 fieldIds[i],
00103 &fieldName,
00104 &fieldSignature,
00105 &generic);
00106 if (error) {
00107 reply->setErrorCode((short) error);
00108 cbk(reply);
00109 return;
00110 }
00111
00112 jint id = (int) fieldIds[i];
00113 *reply << id;
00114 QString name(fieldName);
00115 QString signature(fieldSignature);
00116 *reply << name;
00117 *reply << signature;
00118 error = jvmti->Deallocate((unsigned char*)fieldName);
00119 error = jvmti->Deallocate((unsigned char*)fieldSignature);
00120 error = jvmti->Deallocate((unsigned char*)generic);
00121
00122 jint modBits;
00123 error = jvmti->GetFieldModifiers(
00124 klass,
00125 fieldIds[i],
00126 &modBits);
00127 *reply << modBits;
00128 }
00129 error = jvmti->Deallocate((unsigned char*)fieldIds);
00130 } else {
00131
00132 reply->setErrorCode((short)JVMTI_ERROR_INVALID_CLASS);
00133 }
00134 cbk(reply);
00135 }
00136
00148 void ReferenceTypeCmdSet::getMethods(JDWPCommand* cmd, boost::function< void (JDWPReply*) > cbk)
00149 {
00150 JDWPReply *reply = getJDWPReply(cmd);
00151 qint64 refid;
00152 *cmd >> refid;
00153 jint methodCnt;
00154 jmethodID *methodIds;
00155 jvmtiError error;
00156
00157 if (JDWPCommandSet::getClassMap().contains(refid)) {
00158
00159 jclass klass = JDWPCommandSet::getClassMap().value(refid);
00160 error = jvmti->GetClassMethods(klass, &methodCnt, &methodIds);
00161 if (error) {
00162 reply->setErrorCode((short) error);
00163 cbk(reply);
00164 return;
00165 }
00166 *reply << methodCnt;
00167 for (int i = 0; i < methodCnt; i++) {
00168 char *methodName;
00169 char *methodSignature;
00170 char *generic;
00171
00172 error = jvmti->GetMethodName(
00173 methodIds[i],
00174 &methodName,
00175 &methodSignature,
00176 &generic);
00177 if (error) {
00178 reply->setErrorCode((short) error);
00179 cbk(reply);
00180 return;
00181 }
00182
00183 jint id = (int) methodIds[i];
00184 *reply << id;
00185 QString name(methodName);
00186 QString signature(methodSignature);
00187 *reply << name;
00188 *reply << signature;
00189 error = jvmti->Deallocate((unsigned char*)methodName);
00190 error = jvmti->Deallocate((unsigned char*)methodSignature);
00191 error = jvmti->Deallocate((unsigned char*)generic);
00192
00193 jint modBits;
00194 error = jvmti->GetMethodModifiers(
00195 methodIds[i],
00196 &modBits);
00197 *reply << modBits;
00198 }
00199 error = jvmti->Deallocate((unsigned char*)methodIds);
00200 } else {
00201
00202 reply->setErrorCode((short)JVMTI_ERROR_INVALID_CLASS);
00203 }
00204 cbk(reply);
00205 }
00206
00213 jvmtiError ReferenceTypeCmdSet::getFieldModifierString(jclass &klass, jfieldID &fieldId, QString &modifierStr)
00214 {
00215
00216 jvmtiError error;
00217 jint modBits;
00218
00219 error = jvmti->GetFieldModifiers(klass, fieldId, &modBits);
00220 if (error != JVMTI_ERROR_NONE) {
00221 return error;
00222 }
00223
00224 if ((modBits & JVM_ACC_PUBLIC) == JVM_ACC_PUBLIC) {
00225 modifierStr.append("public ");
00226 }
00227 if ((modBits & JVM_ACC_PRIVATE) == JVM_ACC_PRIVATE) {
00228 modifierStr.append("private ");
00229 }
00230 if ((modBits & JVM_ACC_PROTECTED) == JVM_ACC_PROTECTED) {
00231 modifierStr.append("protected ");
00232 }
00233 if ((modBits & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
00234 modifierStr.append("static ");
00235 }
00236 if ((modBits & JVM_ACC_FINAL) == JVM_ACC_FINAL) {
00237 modifierStr.append("final ");
00238 }
00239 if ((modBits & JVM_ACC_VOLATILE) == JVM_ACC_VOLATILE) {
00240 modifierStr.append("volatile ");
00241 }
00242 if ((modBits & JVM_ACC_TRANSIENT) == JVM_ACC_TRANSIENT) {
00243 modifierStr.append("transient ");
00244 }
00245
00246 modifierStr = modifierStr.trimmed();
00247 return error;
00248 }
00249
00256 jvmtiError ReferenceTypeCmdSet::getMethodModifierString(jmethodID &methodId, QString &modifierStr)
00257 {
00258
00259 jvmtiError error;
00260 jint modBits;
00261 error = jvmti->GetMethodModifiers(methodId, &modBits);
00262 if (error != JVMTI_ERROR_NONE) {
00263 return error;
00264 }
00265
00266 if ((modBits & JVM_ACC_PUBLIC) == JVM_ACC_PUBLIC) {
00267 modifierStr.append("public ");
00268 }
00269 if ((modBits & JVM_ACC_PRIVATE) == JVM_ACC_PRIVATE) {
00270 modifierStr.append("private ");
00271 }
00272 if ((modBits & JVM_ACC_PROTECTED) == JVM_ACC_PROTECTED) {
00273 modifierStr.append("protected ");
00274 }
00275 if ((modBits & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
00276 modifierStr.append("static ");
00277 }
00278 if ((modBits & JVM_ACC_FINAL) == JVM_ACC_FINAL) {
00279 modifierStr.append("final ");
00280 }
00281 if ((modBits & JVM_ACC_SYNCHRONIZED) == JVM_ACC_SYNCHRONIZED) {
00282 modifierStr.append("synchronized ");
00283 }
00284 if ((modBits & JVM_ACC_NATIVE) == JVM_ACC_NATIVE) {
00285 modifierStr.append("native ");
00286 }
00287
00288 modifierStr = modifierStr.trimmed();
00289 return error;
00290 }
00291
00298 jvmtiError ReferenceTypeCmdSet::getClassModifierString(jclass &klass, QString &modifierStr)
00299 {
00300
00301 jint modBits;
00302 jvmtiError error = jvmti->GetClassModifiers(klass, &modBits);
00303 if (error != JVMTI_ERROR_NONE) {
00304 return error;
00305 }
00306
00307 if ((modBits & JVM_ACC_PUBLIC) == JVM_ACC_PUBLIC) {
00308 modifierStr.append("public ");
00309 }
00310 if ((modBits & JVM_ACC_PRIVATE) == JVM_ACC_PRIVATE) {
00311 modifierStr.append("private ");
00312 }
00313 if ((modBits & JVM_ACC_PROTECTED) == JVM_ACC_PROTECTED) {
00314 modifierStr.append("protected ");
00315 }
00316 if ((modBits & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
00317 modifierStr.append("static ");
00318 }
00319 if ((modBits & JVM_ACC_FINAL) == JVM_ACC_FINAL) {
00320 modifierStr.append("final ");
00321 }
00322 if ((modBits & JVM_ACC_ABSTRACT) == JVM_ACC_ABSTRACT) {
00323 modifierStr.append("abstract ");
00324 }
00325
00326 modifierStr = modifierStr.trimmed();
00327 return error;
00328 }
00329
00343 jvmtiError ReferenceTypeCmdSet::getReferenceTypeString(jclass &klass, QString &refType)
00344 {
00345
00346 jvmtiError error;
00347 jboolean type = 0;
00348 error = jvmti->IsInterface(klass, &type);
00349
00350 if (type) {
00351 refType = "interface";
00352 } else {
00353 error = jvmti->IsArrayClass(klass, &type);
00354 if (type) {
00355 refType = "array";
00356 } else {
00357 refType = "class";
00358 }
00359 }
00360 return error;
00361 }
00362
00370 jvmtiError ReferenceTypeCmdSet::getFieldString(jclass &klass, jfieldID &field, QString &fieldSig, QString &name)
00371 {
00372
00373 jvmtiError error;
00374 char *fieldName;
00375 char *fieldSignature;
00376 char *generic;
00377 error = jvmti->GetFieldName(
00378 klass,
00379 field,
00380 &fieldName,
00381 &fieldSignature,
00382 &generic);
00383 if (error) {
00384 return error;
00385 }
00386
00387 fieldSig = fieldSignature;
00388 name = fieldName;
00389
00390 error = jvmti->Deallocate((unsigned char*)fieldName);
00391 error = jvmti->Deallocate((unsigned char*)fieldSignature);
00392 error = jvmti->Deallocate((unsigned char*)generic);
00393
00394 return error;
00395 }
00396
00403 jvmtiError ReferenceTypeCmdSet::getClassSignatureString(jclass &klass, QString &signature)
00404 {
00405
00406 jvmtiError error;
00407 char* jniSignature;
00408 char* genericSignature;
00409
00410 error = jvmti->GetClassSignature(klass, &jniSignature, &genericSignature);
00411 check_jvmti_error(jvmti, error, "Error getting class signature\n");
00412 signature = jniSignature;
00413 error = jvmti->Deallocate((unsigned char*)jniSignature);
00414 error = jvmti->Deallocate((unsigned char*)genericSignature);
00415 return error;
00416 }
00417
00425 jvmtiError ReferenceTypeCmdSet::getMethodSignatureString(jmethodID &methodId, QString &signature, QString &name)
00426 {
00427
00428 jvmtiError error;
00429
00430 char *methodName;
00431 char *methodSignature;
00432 char *generic;
00433
00434 error = jvmti->GetMethodName(
00435 methodId,
00436 &methodName,
00437 &methodSignature,
00438 &generic);
00439 if (error) {
00440 return error;
00441 }
00442
00443 name = methodName;
00444 signature = methodSignature;
00445
00446 error = jvmti->Deallocate((unsigned char*)methodName);
00447 error = jvmti->Deallocate((unsigned char*)methodSignature);
00448 error = jvmti->Deallocate((unsigned char*)generic);
00449
00450 return error;
00451 }
00452
00453 }
00454 }
00455 }