static jboolean lastCommand(jdwpCmdPacket *cmd) { if ((cmd->cmdSet == JDWP_COMMAND_SET(VirtualMachine)) && ((cmd->cmd == JDWP_COMMAND(VirtualMachine, Dispose)) || (cmd->cmd == JDWP_COMMAND(VirtualMachine, Exit)))) { return JNI_TRUE; } else { return JNI_FALSE; } }
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)); */ }
static jboolean resumeCommand(jdwpCmdPacket *cmd) { if ( (cmd->cmdSet == JDWP_COMMAND_SET(VirtualMachine)) && (cmd->cmd == JDWP_COMMAND(VirtualMachine, Resume)) ) { return JNI_TRUE; } else { return JNI_FALSE; } }
void VMEvent::vmdeath(Transport *transport) { // check_notify_wanted(Dbg_EventKind_VM_DEATH); PacketOutputStream out(transport, JDWP_EVENT_VMDEATH_LEN, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); DEBUGGER_EVENT(("VM Death")); out.write_byte(JDWP_SuspendPolicy_ALL); out.write_int(1); out.write_byte(JDWP_EventKind_VM_DEATH); out.write_int(0); /* spec says always zero */ out.send_packet(); }
void VMEvent::vminit(Transport *t) { int reqID = PacketStream::unique_id() /* side-effects*/; (void)reqID; int threadID = JavaDebugger::get_thread_id_by_ref(Thread::current()); bool is_suspend = true; PacketOutputStream out(t, JDWP_EVENT_VMINIT_LEN, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); if ((is_suspend = JavaDebugger::is_suspend()) != false) { // Suspend all threads by default DEBUGGER_EVENT(("VM Suspend All")); out.write_byte(JDWP_SuspendPolicy_ALL); } else { // Suspend no threads DEBUGGER_EVENT(("VM Suspend None")); out.write_byte(JDWP_SuspendPolicy_NONE); } out.write_int(1); out.write_byte(JDWP_EventKind_VM_START); out.write_int(0); out.write_int(threadID); out.send_packet(); if (is_suspend) { // Use suspend policy which suspends all threads by default JavaDebugger::process_suspend_policy(JDWP_SuspendPolicy_ALL, Thread::current(), true); } else { // Use suspend policy which suspends no threads DEBUGGER_EVENT(("VM SuspendPolicy not specified")); JavaDebugger::process_suspend_policy(JDWP_SuspendPolicy_NONE, Thread::current(), true); } if (_debugger_active) { JavaDebugger::send_all_class_prepares(); } }
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); }
void VMEvent::send_event(DebuggerEvent *d_event) { check_notify_wanted(JDWP_eventkind_to_dbg_eventkind(d_event->event_kind())); UsingFastOops fast_oops; VMEvent::Fast ep, ep_2; JavaClass::Fast jc; int event_count = 0; jbyte suspend_policy = JDWP_SuspendPolicy_NONE; int data_len = JDWP_EVENT_LEN; ep = ep_2 = get_event_request(d_event, event_count, suspend_policy); if (ep.is_null()) { return; } // Flush any packets waiting in the queue. This helps avoid a race // condition where we may have a resume command in the queue for a // previous event, we send this event, process the resume command // out of order JavaDebugger::dispatch(0); // Calculate packet length while (ep_2.not_null()) { switch(ep_2().event_kind()) { case JDWP_EventKind_SINGLE_STEP: case JDWP_EventKind_BREAKPOINT: data_len += JDWP_EVENT_BREAK_LEN; break; case JDWP_EventKind_THREAD_START: case JDWP_EventKind_THREAD_DEATH: data_len += JDWP_EVENT_THREAD_LEN; break; case JDWP_EventKind_CLASS_PREPARE: case JDWP_EventKind_CLASS_LOAD: jc = JavaDebugger::get_object_by_id(d_event->clazz_id()); data_len += (9 + class_prepare_info_length(&jc)); break; case JDWP_EventKind_CLASS_UNLOAD: jc = JavaDebugger::get_object_by_id(d_event->clazz_id()); data_len += (5 + PacketOutputStream::get_class_name_length(&jc)); break; } ep_2 = ep_2().send_next(); } Transport::Fast transport = ep().transport(); PacketOutputStream out(&transport, data_len, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); UsingFastOops fast_oops_2; Thread::Fast thread = JavaDebugger::get_thread_by_id(d_event->thread_id()); if (thread.is_null()) { // Some events were created before any threads were ready, so just // use the current thread thread = Thread::current(); } DEBUGGER_EVENT(("VM Event xprt=0x%x, thrd=0x%x, id=0x%x, kind=0x%x, susp.=0x%x", transport.obj(), d_event->thread_id(), ep().event_id(), ep().event_kind(), suspend_policy)); out.write_byte(suspend_policy); out.write_int(event_count); while (ep.not_null()) { // transport = ep().transport(); // out.set_transport(&transport); out.write_byte(ep().event_kind()); out.write_int(ep().event_id()); switch(ep().event_kind()) { case JDWP_EventKind_SINGLE_STEP: case JDWP_EventKind_BREAKPOINT: { UsingFastOops fast_oops_3; out.write_int(d_event->thread_id()); DEBUGGER_EVENT(("Event clss=0x%x, mthd=0x%x, off=0x%x", d_event->clazz_id(), (int)(d_event->method_id() & 0xFFFFFFFF), d_event->offset())); #ifdef AZZERT if (TraceDebugger) { InstanceClass::Raw ic = JavaDebugger::get_object_by_id(d_event->clazz_id()); Method::Raw m = JavaDebugger::get_method_by_id(&ic, d_event->method_id()); m().print_name_on(tty); tty->cr(); } #endif d_event->write_as_location(&out); // IMPL_NOTE: I don't think we can ever get here with a compiled frame VMEventModifier::deoptimize_frame(&thread); break; } case JDWP_EventKind_THREAD_START: case JDWP_EventKind_THREAD_DEATH: out.write_int(d_event->thread_id()); break; case JDWP_EventKind_CLASS_PREPARE: case JDWP_EventKind_CLASS_LOAD: { out.write_int(d_event->thread_id()); DEBUGGER_EVENT(("Event clss=0x%x", d_event->clazz_id())); jc = JavaDebugger::get_object_by_id(d_event->clazz_id()); #ifdef AZZERT if (TraceDebugger) { jc().print_name_on(tty); tty->cr(); } #endif out.write_class_prepare_info(&jc); break; } case JDWP_EventKind_CLASS_UNLOAD: { jc = JavaDebugger::get_object_by_id(d_event->clazz_id()); out.write_class_name(&jc); break; } } ep = ep().send_next(); } out.send_packet(); JavaDebugger::process_suspend_policy(suspend_policy, &thread, false); }
void VMEvent::exception_event(Throwable *exception, JavaFrame *catch_frame, DebuggerEvent *d_event, int catch_offset) { check_notify_wanted(Dbg_EventKind_EXCEPTION); UsingFastOops fast_oops; VMEvent::Fast ep, ep_2; jlong throw_offset = 0; int event_count = 0; jbyte suspend_policy = JDWP_SuspendPolicy_NONE; InstanceClass::Fast ic; LocationModifier::Fast location; Method::Fast catch_method; Method::Fast throw_method; int data_len = JDWP_EVENT_LEN; ep = ep_2 = get_event_request(d_event, event_count, suspend_policy); if (ep.is_null()) { return; } // Flush any packets waiting in the queue. This helps avoid a race // condition where we may have a resume command in the queue for a // previous event, we send this event, process the resume command // out of order JavaDebugger::dispatch(0); // Calculate packet length data_len += (JDWP_EVENT_EXCEPTION_LEN * event_count); Transport::Fast transport = ep().transport(); PacketOutputStream out(&transport, data_len, JDWP_COMMAND_SET(Event), JDWP_COMMAND(Event, Composite)); // Create a buffered output stream so we can asynchronously send an error // Calculate the size based on half of the items being 'longs' UsingFastOops fast_oops_2; Thread::Fast thread = JavaDebugger::get_thread_by_id(d_event->thread_id()); VMEventModifier::deoptimize_frame(&thread, true); VMEvent::Fast info_event = find_event((jbyte)VM_EXCEPTION_INFO_EVENT); if (!info_event.is_null()) { location = get_modifier(&info_event, JDWP_EventRequest_Set_Out_modifiers_Modifier_LocationOnly); GUARANTEE(!location.is_null(), "No location modifier in info event"); throw_method = location().method(); throw_offset = location().offset(); remove_event_request(&info_event); } else { UsingFastOops fast_oops_3; ObjArray::Fast trace, methods; TypeArray::Fast offsets; trace = exception->backtrace(); if (!trace.is_null()) { methods = trace().obj_at(0); offsets = trace().obj_at(1); if (!methods.is_null() && !offsets.is_null()) { throw_method = methods().obj_at(0); throw_offset = (jlong)(offsets().int_at(0)); } } } DEBUGGER_EVENT(("Exception")); out.write_byte(suspend_policy); out.write_int(event_count); while (ep.not_null()) { out.write_byte(JDWP_EventKind_EXCEPTION); out.write_int(ep().event_id()); // thread with exception out.write_int(d_event->thread_id()); // location of exception throw if (throw_method.not_null()) { ic = throw_method().holder(); } DebuggerEvent throw_event(JDWP_EventKind_EXCEPTION, 0, // don't need thread JavaDebugger::get_object_id_by_ref(&ic), JavaDebugger::get_method_id(&ic, &throw_method), (jlong)throw_offset); throw_event.write_as_location(&out); // thrown exception out.write_byte('L'); out.write_object(exception); // location of catch, or 0 if not caught if (catch_frame == NULL) { LocationModifier::write_null_location(&out); } else { catch_method = catch_frame->method(); ic = catch_method().holder(); DebuggerEvent catch_event(JDWP_EventKind_EXCEPTION, 0, // don't need thread JavaDebugger::get_object_id_by_ref(&ic), JavaDebugger::get_method_id(&ic, &catch_method), (jlong)catch_offset); catch_event.write_as_location(&out); } ep = ep().send_next(); } out.send_packet(); JavaDebugger::process_suspend_policy(suspend_policy, &thread, true); }