virtualmachineimpl.c
来自「This is a resource based on j2me embedde」· C语言 代码 · 共 910 行 · 第 1/2 页
C
910 行
/* * @(#)VirtualMachineImpl.c 1.100 05/03/08 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. */#include "util.h"#include "VirtualMachineImpl.h"#include "commonRef.h"#include "inStream.h"#include "outStream.h"#include "eventHandler.h"#include "eventHelper.h"#include "threadControl.h"#include "SDE.h"#include "FrameID.h"static char *versionName = "Java Debug Wire Protocol";static int majorVersion = 1; /* JDWP major version */static int minorVersion = 6; /* JDWP minor version */static jboolean version(PacketInputStream *in, PacketOutputStream *out){ char buf[500]; char *vmName; char *vmVersion; char *vmInfo; if (gdata->vmDead) { outStream_setError(out, JDWP_ERROR(VM_DEAD)); return JNI_TRUE; } vmVersion = gdata->property_java_version; if (vmVersion == NULL) { vmVersion = "<unknown>"; } vmName = gdata->property_java_vm_name; if (vmName == NULL) { vmName = "<unknown>"; } vmInfo = gdata->property_java_vm_info; if (vmInfo == NULL) { vmInfo = "<unknown>"; } /* * Write the descriptive version information */ (void)snprintf(buf, sizeof(buf), "%s version %d.%d\nJVM Debug Interface version %d.%d\n" "JVM version %s (%s, %s)", versionName, majorVersion, minorVersion, jvmtiMajorVersion(), jvmtiMinorVersion(), vmVersion, vmName, vmInfo); (void)outStream_writeString(out, buf); /* * Write the JDWP version numbers */ (void)outStream_writeInt(out, majorVersion); (void)outStream_writeInt(out, minorVersion); /* * Write the VM version and name */ (void)outStream_writeString(out, vmVersion); (void)outStream_writeString(out, vmName); return JNI_TRUE;}static jboolean classesForSignature(PacketInputStream *in, PacketOutputStream *out) { JNIEnv *env; char *signature; if (gdata->vmDead) { outStream_setError(out, JDWP_ERROR(VM_DEAD)); return JNI_TRUE; } signature = inStream_readString(in); if (signature == NULL) { outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY)); return JNI_TRUE; } if (inStream_error(in)) { return JNI_TRUE; } env = getEnv(); WITH_LOCAL_REFS(env, 2000) { jint classCount; jclass *theClasses; jvmtiError error; error = allLoadedClasses(&theClasses, &classCount); if ( error == JVMTI_ERROR_NONE ) { /* Count classes in theClasses which match signature */ int matchCount = 0; /* Count classes written to the JDWP connection */ int writtenCount = 0; int i; for (i=0; i<classCount; i++) { jclass clazz = theClasses[i]; jint status = classStatus(clazz); char *candidate_signature = NULL; jint wanted = (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY| JVMTI_CLASS_STATUS_PRIMITIVE); /* We want prepared classes, primitives, and arrays only */ if ((status & wanted) == 0) { continue; } error = classSignature(clazz, &candidate_signature, NULL); if (error != JVMTI_ERROR_NONE) { break; } if (strcmp(candidate_signature, signature) == 0) { /* Float interesting classes (those that * are matching and are prepared) to the * beginning of the array. */ theClasses[i] = theClasses[matchCount]; theClasses[matchCount++] = clazz; } jvmtiDeallocate(candidate_signature); } /* At this point matching prepared classes occupy * indicies 0 thru matchCount-1 of theClasses. */ if ( error == JVMTI_ERROR_NONE ) { (void)outStream_writeInt(out, matchCount); for (; writtenCount < matchCount; writtenCount++) { jclass clazz = theClasses[writtenCount]; jint status = classStatus(clazz); jbyte tag = referenceTypeTag(clazz); (void)outStream_writeByte(out, tag); outStream_writeObjectRef(env, out, clazz); (void)outStream_writeInt(out, map2jdwpClassStatus(status)); /* No point in continuing if there's an error */ if (outStream_error(out)) { break; } } } } if ( error != JVMTI_ERROR_NONE ) { outStream_setError(out, map2jdwpError(error)); } } END_WITH_LOCAL_REFS(env); jvmtiDeallocate(signature); return JNI_TRUE;}static jboolean allClasses1(PacketInputStream *in, PacketOutputStream *out, int outputGenerics){ JNIEnv *env; if (gdata->vmDead) { outStream_setError(out, JDWP_ERROR(VM_DEAD)); return JNI_TRUE; } env = getEnv(); WITH_LOCAL_REFS(env, 2000) { jint classCount; jclass *theClasses; jvmtiError error; error = allLoadedClasses(&theClasses, &classCount); if ( error != JVMTI_ERROR_NONE ) { outStream_setError(out, map2jdwpError(error)); } else { /* Count classes in theClasses which are prepared */ int prepCount = 0; /* Count classes written to the JDWP connection */ int writtenCount = 0; int i; for (i=0; i<classCount; i++) { jclass clazz = theClasses[i]; jint status = classStatus(clazz); jint wanted = (JVMTI_CLASS_STATUS_PREPARED|JVMTI_CLASS_STATUS_ARRAY); /* We want prepared classes and arrays only */ if ((status & wanted) != 0) { /* Float interesting classes (those that * are prepared) to the beginning of the array. */ theClasses[i] = theClasses[prepCount]; theClasses[prepCount++] = clazz; } } /* At this point prepared classes occupy * indicies 0 thru prepCount-1 of theClasses. */ (void)outStream_writeInt(out, prepCount); for (; writtenCount < prepCount; writtenCount++) { char *signature = NULL; char *genericSignature = NULL; jclass clazz = theClasses[writtenCount]; jint status = classStatus(clazz); jbyte tag = referenceTypeTag(clazz); jvmtiError error; error = classSignature(clazz, &signature, &genericSignature); if (error != JVMTI_ERROR_NONE) { outStream_setError(out, map2jdwpError(error)); break; } (void)outStream_writeByte(out, tag); outStream_writeObjectRef(env, out, clazz); (void)outStream_writeString(out, signature); if (outputGenerics == 1) { writeGenericSignature(out, genericSignature); } (void)outStream_writeInt(out, map2jdwpClassStatus(status)); jvmtiDeallocate(signature); if (genericSignature != NULL) { jvmtiDeallocate(genericSignature); } /* No point in continuing if there's an error */ if (outStream_error(out)) { break; } } } } END_WITH_LOCAL_REFS(env); return JNI_TRUE;}static jboolean allClasses(PacketInputStream *in, PacketOutputStream *out){ return allClasses1(in, out, 0);}static jboolean allClassesWithGeneric(PacketInputStream *in, PacketOutputStream *out){ return allClasses1(in, out, 1);} /***********************************************************/static jbooleaninstanceCounts(PacketInputStream *in, PacketOutputStream *out){ jint classCount; jclass *classes; JNIEnv *env; int ii; if (gdata->vmDead) { outStream_setError(out, JDWP_ERROR(VM_DEAD)); return JNI_TRUE; } classCount = inStream_readInt(in); if (inStream_error(in)) { return JNI_TRUE; } if (classCount == 0) { (void)outStream_writeInt(out, 0); return JNI_TRUE; } if (classCount < 0) { outStream_setError(out, JDWP_ERROR(ILLEGAL_ARGUMENT)); return JNI_TRUE; } env = getEnv(); classes = jvmtiAllocate(classCount * (int)sizeof(jclass)); for (ii = 0; ii < classCount; ii++) { jdwpError errorCode; classes[ii] = inStream_readClassRef(env, in); errorCode = inStream_error(in); if (errorCode != JDWP_ERROR(NONE)) { /* * A class could have been unloaded/gc'd so * if we get an error, just ignore it and keep * going. An instanceCount of 0 will be returned. */ if (errorCode == JDWP_ERROR(INVALID_OBJECT) || errorCode == JDWP_ERROR(INVALID_CLASS)) { inStream_clearError(in); classes[ii] = NULL; continue; } jvmtiDeallocate(classes); return JNI_TRUE; } } WITH_LOCAL_REFS(env, 1) { jlong *counts; jvmtiError error; counts = jvmtiAllocate(classCount * (int)sizeof(jlong)); /* Iterate over heap getting info on these classes */ error = classInstanceCounts(classCount, classes, counts); if (error != JVMTI_ERROR_NONE) { outStream_setError(out, map2jdwpError(error)); } else { (void)outStream_writeInt(out, classCount); for (ii = 0; ii < classCount; ii++) { (void)outStream_writeLong(out, counts[ii]); } } jvmtiDeallocate(counts); } END_WITH_LOCAL_REFS(env); jvmtiDeallocate(classes); return JNI_TRUE;}static jboolean redefineClasses(PacketInputStream *in, PacketOutputStream *out) { jvmtiClassDefinition *classDefs; jboolean ok = JNI_TRUE; jint classCount; jint i; JNIEnv *env; if (gdata->vmDead) { /* quietly ignore */ return JNI_TRUE; } classCount = inStream_readInt(in); if (inStream_error(in)) { return JNI_TRUE; } if ( classCount == 0 ) { return JNI_TRUE; } /*LINTED*/ classDefs = jvmtiAllocate(classCount*(int)sizeof(jvmtiClassDefinition)); if (classDefs == NULL) { outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY)); return JNI_TRUE; } /*LINTED*/ (void)memset(classDefs, 0, classCount*sizeof(jvmtiClassDefinition)); env = getEnv(); for (i = 0; i < classCount; ++i) { int byteCount; unsigned char * bytes; jclass clazz; clazz = inStream_readClassRef(env, in); if (inStream_error(in)) { ok = JNI_FALSE; break; } byteCount = inStream_readInt(in); if (inStream_error(in)) { ok = JNI_FALSE; break; } if ( byteCount <= 0 ) { outStream_setError(out, JDWP_ERROR(INVALID_CLASS_FORMAT)); ok = JNI_FALSE; break; } bytes = (unsigned char *)jvmtiAllocate(byteCount); if (bytes == NULL) { outStream_setError(out, JDWP_ERROR(OUT_OF_MEMORY)); ok = JNI_FALSE; break; } (void)inStream_readBytes(in, byteCount, (jbyte *)bytes); if (inStream_error(in)) { ok = JNI_FALSE; break; } classDefs[i].klass = clazz; classDefs[i].class_byte_count = byteCount; classDefs[i].class_bytes = bytes; } if (ok == JNI_TRUE) { jvmtiError error; error = JVMTI_FUNC_PTR(gdata->jvmti,RedefineClasses) (gdata->jvmti, classCount, classDefs); if (error != JVMTI_ERROR_NONE) { outStream_setError(out, map2jdwpError(error)); } else { /* zap our BP info */ for ( i = 0 ; i < classCount; i++ ) { eventHandler_freeClassBreakpoints(classDefs[i].klass); } } } /* free up allocated memory */ for ( i = 0 ; i < classCount; i++ ) { if ( classDefs[i].class_bytes != NULL ) { jvmtiDeallocate((void*)classDefs[i].class_bytes); } } jvmtiDeallocate(classDefs); return JNI_TRUE;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?