static void handleReportVMInitCommand(JNIEnv* env, ReportVMInitCommand *command) { PacketOutputStream out; if (command->suspendPolicy == JDWP_SUSPEND_POLICY(ALL)) { (void)threadControl_suspendAll(); } else if (command->suspendPolicy == JDWP_SUSPEND_POLICY(EVENT_THREAD)) { (void)threadControl_suspendThread(command->thread, JNI_FALSE); } outStream_initCommand(&out, uniqueID(), 0x0, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); (void)outStream_writeByte(&out, command->suspendPolicy); (void)outStream_writeInt(&out, 1); /* Always one component */ (void)outStream_writeByte(&out, JDWP_EVENT(VM_INIT)); (void)outStream_writeInt(&out, 0); /* Not in response to an event req. */ (void)outStream_writeObjectRef(env, &out, command->thread); outStream_sendCommand(&out); outStream_destroy(&out); /* Why aren't we tossing this: tossGlobalRef(env, &(command->thread)); */ }
void outStream_writeValue(JNIEnv *env, PacketOutputStream *out, jbyte typeKey, jvalue value) { if (typeKey == JDWP_Tag_OBJECT) { outStream_writeByte(out, specificTypeKey(value.l)); } else { outStream_writeByte(out, typeKey); } if (isObjectTag(typeKey)) { WRITE_GLOBAL_REF(env, out, value.l); } else { switch (typeKey) { case JDWP_Tag_BYTE: outStream_writeByte(out, value.b); break; case JDWP_Tag_CHAR: outStream_writeChar(out, value.c); break; case JDWP_Tag_FLOAT: outStream_writeFloat(out, value.f); break; case JDWP_Tag_DOUBLE: outStream_writeDouble(out, value.d); break; case JDWP_Tag_INT: outStream_writeInt(out, value.i); break; case JDWP_Tag_LONG: outStream_writeLong(out, value.j); break; case JDWP_Tag_SHORT: outStream_writeShort(out, value.s); break; case JDWP_Tag_BOOLEAN: outStream_writeBoolean(out, value.z); break; case JDWP_Tag_VOID: /* happens with function return values */ /* write nothing */ break; default: ERROR_MESSAGE_EXIT("Invalid type key"); } } }
jdwpError outStream_writeValue(JNIEnv *env, PacketOutputStream *out, jbyte typeKey, jvalue value) { if (typeKey == JDWP_TAG(OBJECT)) { (void)outStream_writeByte(out, specificTypeKey(env, value.l)); } else { (void)outStream_writeByte(out, typeKey); } if (isObjectTag(typeKey)) { (void)outStream_writeObjectRef(env, out, value.l); } else { switch (typeKey) { case JDWP_TAG(BYTE): return outStream_writeByte(out, value.b); case JDWP_TAG(CHAR): return outStream_writeChar(out, value.c); case JDWP_TAG(FLOAT): return outStream_writeFloat(out, value.f); case JDWP_TAG(DOUBLE): return outStream_writeDouble(out, value.d); case JDWP_TAG(INT): return outStream_writeInt(out, value.i); case JDWP_TAG(LONG): return outStream_writeLong(out, value.j); case JDWP_TAG(SHORT): return outStream_writeShort(out, value.s); case JDWP_TAG(BOOLEAN): return outStream_writeBoolean(out, value.z); case JDWP_TAG(VOID): /* happens with function return values */ /* write nothing */ return JDWP_ERROR(NONE); default: EXIT_ERROR(AGENT_ERROR_INVALID_OBJECT,"Invalid type key"); break; } } return JDWP_ERROR(NONE); }
static jboolean reflectedType(PacketInputStream *in, PacketOutputStream *out) { jbyte tag; jobject object; JNIEnv *env; env = getEnv(); object = inStream_readObjectRef(env, in); if (inStream_error(in)) { return JNI_TRUE; } /* * In our implementation, the reference type id is the same as the * class object id, so we bounce it right back. * */ tag = referenceTypeTag(object); (void)outStream_writeByte(out, tag); (void)outStream_writeObjectRef(env, out, object); return JNI_TRUE; }
jdwpError outStream_skipBytes(PacketOutputStream *stream, jint count) { int i; for (i = 0; i < count; i++) { (void)outStream_writeByte(stream, 0); } return stream->error; }
static void handleUnloadCommandSingle(JNIEnv* env, PacketOutputStream *out, UnloadCommandSingle *command) { (void)outStream_writeByte(out, JDWP_EVENT(CLASS_UNLOAD)); (void)outStream_writeInt(out, command->id); (void)outStream_writeString(out, command->classSignature); jvmtiDeallocate(command->classSignature); command->classSignature = NULL; }
static void handleFrameEventCommandSingle(JNIEnv* env, PacketOutputStream *out, FrameEventCommandSingle *command) { if (command->typeKey) { (void)outStream_writeByte(out, JDWP_EVENT(METHOD_EXIT_WITH_RETURN_VALUE)); } else { (void)outStream_writeByte(out, eventIndex2jdwp(command->ei)); } (void)outStream_writeInt(out, command->id); (void)outStream_writeObjectRef(env, out, command->thread); writeCodeLocation(out, command->clazz, command->method, command->location); if (command->typeKey) { (void)outStream_writeValue(env, out, command->typeKey, command->returnValue); if (isObjectTag(command->typeKey) && command->returnValue.l != NULL) { tossGlobalRef(env, &(command->returnValue.l)); } } tossGlobalRef(env, &(command->thread)); tossGlobalRef(env, &(command->clazz)); }
static void writeFieldAccessEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo) { jbyte fieldClassTag; fieldClassTag = referenceTypeTag(evinfo->u.field_access.field_clazz); (void)outStream_writeObjectRef(env, out, evinfo->thread); writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location); (void)outStream_writeByte(out, fieldClassTag); (void)outStream_writeObjectRef(env, out, evinfo->u.field_access.field_clazz); (void)outStream_writeFieldID(out, evinfo->u.field_access.field); (void)outStream_writeObjectTag(env, out, evinfo->object); (void)outStream_writeObjectRef(env, out, evinfo->object); }
static void handleEventCommandSingle(JNIEnv *env, PacketOutputStream *out, EventCommandSingle *command) { EventInfo *evinfo = &command->info; (void)outStream_writeByte(out, eventIndex2jdwp(evinfo->ei)); (void)outStream_writeInt(out, command->id); switch (evinfo->ei) { case EI_SINGLE_STEP: writeSingleStepEvent(env, out, evinfo); break; case EI_BREAKPOINT: writeBreakpointEvent(env, out, evinfo); break; case EI_FIELD_ACCESS: writeFieldAccessEvent(env, out, evinfo); break; case EI_FIELD_MODIFICATION: writeFieldModificationEvent(env, out, evinfo); break; case EI_EXCEPTION: writeExceptionEvent(env, out, evinfo); break; case EI_THREAD_START: case EI_THREAD_END: writeThreadEvent(env, out, evinfo); break; case EI_CLASS_LOAD: case EI_CLASS_PREPARE: writeClassEvent(env, out, evinfo); break; case EI_MONITOR_CONTENDED_ENTER: case EI_MONITOR_CONTENDED_ENTERED: case EI_MONITOR_WAIT: case EI_MONITOR_WAITED: writeMonitorEvent(env, out, evinfo); break; case EI_VM_DEATH: writeVMDeathEvent(env, out, evinfo); break; default: EXIT_ERROR(AGENT_ERROR_INVALID_EVENT_TYPE,"unknown event index"); break; } tossEventInfoRefs(env, evinfo); }
static void writeByteComponents(JNIEnv *env, PacketOutputStream *out, jarray array, jint index, jint length) { jbyte *components; components = newComponents(out, length, sizeof(jbyte)); if (components != NULL) { jint i; JNI_FUNC_PTR(env,GetByteArrayRegion)(env, array, index, length, components); for (i = 0; i < length; i++) { (void)outStream_writeByte(out, components[i]); } deleteComponents(components); } }
WITH_LOCAL_REFS(env, length) { int i; jobject component; for (i = 0; i < length; i++) { component = JNI_FUNC_PTR(env,GetObjectArrayElement)(env, array, index + i); if (JNI_FUNC_PTR(env,ExceptionOccurred)(env)) { /* cleared by caller */ break; } (void)outStream_writeByte(out, specificTypeKey(env, component)); (void)outStream_writeObjectRef(env, out, component); } } END_WITH_LOCAL_REFS(env);
static void writeFieldModificationEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo) { jbyte fieldClassTag; fieldClassTag = referenceTypeTag(evinfo->u.field_modification.field_clazz); (void)outStream_writeObjectRef(env, out, evinfo->thread); writeCodeLocation(out, evinfo->clazz, evinfo->method, evinfo->location); (void)outStream_writeByte(out, fieldClassTag); (void)outStream_writeObjectRef(env, out, evinfo->u.field_modification.field_clazz); (void)outStream_writeFieldID(out, evinfo->u.field_modification.field); (void)outStream_writeObjectTag(env, out, evinfo->object); (void)outStream_writeObjectRef(env, out, evinfo->object); (void)outStream_writeValue(env, out, (jbyte)evinfo->u.field_modification.signature_type, evinfo->u.field_modification.new_value); }
static void writeClassEvent(JNIEnv *env, PacketOutputStream *out, EventInfo *evinfo) { jbyte classTag; jint status; char *signature = NULL; jvmtiError error; classTag = referenceTypeTag(evinfo->clazz); error = classSignature(evinfo->clazz, &signature, NULL); if (error != JVMTI_ERROR_NONE) { EXIT_ERROR(error,"signature"); } status = classStatus(evinfo->clazz); (void)outStream_writeObjectRef(env, out, evinfo->thread); (void)outStream_writeByte(out, classTag); (void)outStream_writeObjectRef(env, out, evinfo->clazz); (void)outStream_writeString(out, signature); (void)outStream_writeInt(out, map2jdwpClassStatus(status)); jvmtiDeallocate(signature); }
static void handleReportEventCompositeCommand(JNIEnv *env, ReportEventCompositeCommand *recc) { PacketOutputStream out; jint count = recc->eventCount; jint i; if (recc->suspendPolicy != JDWP_SUSPEND_POLICY(NONE)) { /* must determine thread to interrupt before writing */ /* since writing destroys it */ jthread thread = NULL; for (i = 0; i < count; i++) { CommandSingle *single = &(recc->singleCommand[i]); switch (single->singleKind) { case COMMAND_SINGLE_EVENT: thread = single->u.eventCommand.info.thread; break; case COMMAND_SINGLE_FRAME_EVENT: thread = single->u.frameEventCommand.thread; break; } if (thread != NULL) { break; } } if (thread == NULL) { (void)threadControl_suspendAll(); } else { suspendWithInvokeEnabled(recc->suspendPolicy, thread); } } outStream_initCommand(&out, uniqueID(), 0x0, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); (void)outStream_writeByte(&out, recc->suspendPolicy); (void)outStream_writeInt(&out, count); for (i = 0; i < count; i++) { CommandSingle *single = &(recc->singleCommand[i]); switch (single->singleKind) { case COMMAND_SINGLE_EVENT: handleEventCommandSingle(env, &out, &single->u.eventCommand); break; case COMMAND_SINGLE_UNLOAD: handleUnloadCommandSingle(env, &out, &single->u.unloadCommand); break; case COMMAND_SINGLE_FRAME_EVENT: handleFrameEventCommandSingle(env, &out, &single->u.frameEventCommand); break; } } outStream_sendCommand(&out); outStream_destroy(&out); }
jdwpError outStream_writeObjectTag(JNIEnv *env, PacketOutputStream *stream, jobject val) { return outStream_writeByte(stream, specificTypeKey(env, val)); }
jint outStream_writeObjectTag(PacketOutputStream *stream, jobject val) { return outStream_writeByte(stream, specificTypeKey(val)); }