Esempio n. 1
0
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)); */
}
Esempio n. 2
0
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;
    }
}
Esempio n. 3
0
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;
    }
}
Esempio n. 4
0
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();
}
Esempio n. 5
0
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();
  }
}
Esempio n. 6
0
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);
}
Esempio n. 7
0
void 
debugDispatch_initialize(void)
{
    /*
     * Create the level-one (CommandSet) dispatch table.
     * Zero the table so that unknown CommandSets do not
     * cause random errors.
     */
    l1Array = jvmtiAllocate((JDWP_HIGHEST_COMMAND_SET+1) * sizeof(void *));

    if (l1Array == NULL) {
	EXIT_ERROR(JVMTI_ERROR_OUT_OF_MEMORY,"command set array");
    }

    (void)memset(l1Array, 0, (JDWP_HIGHEST_COMMAND_SET+1) * sizeof(void *));

    /*
     * Create the level-two (Command) dispatch tables to the
     * corresponding slots in the CommandSet dispatch table..
     */
    l1Array[JDWP_COMMAND_SET(VirtualMachine)] = (void *)VirtualMachine_Cmds;
    l1Array[JDWP_COMMAND_SET(ReferenceType)] = (void *)ReferenceType_Cmds;
    l1Array[JDWP_COMMAND_SET(ClassType)] = (void *)ClassType_Cmds;
    l1Array[JDWP_COMMAND_SET(ArrayType)] = (void *)ArrayType_Cmds;

    l1Array[JDWP_COMMAND_SET(Field)] = (void *)Field_Cmds;
    l1Array[JDWP_COMMAND_SET(Method)] = (void *)Method_Cmds;
    l1Array[JDWP_COMMAND_SET(ObjectReference)] = (void *)ObjectReference_Cmds;
    l1Array[JDWP_COMMAND_SET(StringReference)] = (void *)StringReference_Cmds;
    l1Array[JDWP_COMMAND_SET(ThreadReference)] = (void *)ThreadReference_Cmds;
    l1Array[JDWP_COMMAND_SET(ThreadGroupReference)] = (void *)ThreadGroupReference_Cmds;
    l1Array[JDWP_COMMAND_SET(ClassLoaderReference)] = (void *)ClassLoaderReference_Cmds;
    l1Array[JDWP_COMMAND_SET(ArrayReference)] = (void *)ArrayReference_Cmds;
    l1Array[JDWP_COMMAND_SET(EventRequest)] = (void *)EventRequest_Cmds;
    l1Array[JDWP_COMMAND_SET(StackFrame)] = (void *)StackFrame_Cmds;
    l1Array[JDWP_COMMAND_SET(ClassObjectReference)] = (void *)ClassObjectReference_Cmds;
}
Esempio n. 8
0
void
debugLoop_run(void)
{
    jboolean shouldListen;
    jdwpPacket p;
    jvmtiStartFunction func;

    /* Initialize all statics */
    /* We may be starting a new connection after an error */
    cmdQueue = NULL;
    cmdQueueLock = debugMonitorCreate("JDWP Command Queue Lock");
    transportError = JNI_FALSE;

    shouldListen = JNI_TRUE;

    func = &reader;
    (void)spawnNewThread(func, NULL, "JDWP Command Reader");

    standardHandlers_onConnect();
    threadControl_onConnect();

    /* Okay, start reading cmds! */
    while (shouldListen) {
        if (!dequeue(&p)) {
            break;
        }

        if (p.type.cmd.flags & JDWPTRANSPORT_FLAGS_REPLY) {
            /*
             * Its a reply packet.
             */
           continue;
        } else {
            /*
             * Its a cmd packet.
             */
            jdwpCmdPacket *cmd = &p.type.cmd;
            PacketInputStream in;
            PacketOutputStream out;
            CommandHandler func;

            /* Should reply be sent to sender.
             * For error handling, assume yes, since
             * only VM/exit does not reply
             */
            jboolean replyToSender = JNI_TRUE;

            /*
             * For VirtualMachine.Resume commands we hold the resumeLock
             * while executing and replying to the command. This ensures
             * that a Resume after VM_DEATH will be allowed to complete
             * before the thread posting the VM_DEATH continues VM
             * termination.
             */
            if (resumeCommand(cmd)) {
                debugMonitorEnter(resumeLock);
            }

            /* Initialize the input and output streams */
            inStream_init(&in, p);
            outStream_initReply(&out, inStream_id(&in));

            LOG_MISC(("Command set %d, command %d", cmd->cmdSet, cmd->cmd));

            func = debugDispatch_getHandler(cmd->cmdSet,cmd->cmd);
            if (func == NULL) {
                /* we've never heard of this, so I guess we
                 * haven't implemented it.
                 * Handle gracefully for future expansion
                 * and platform / vendor expansion.
                 */
                outStream_setError(&out, JDWP_ERROR(NOT_IMPLEMENTED));
            } else if (gdata->vmDead &&
             ((cmd->cmdSet) != JDWP_COMMAND_SET(VirtualMachine))) {
                /* Protect the VM from calls while dead.
                 * VirtualMachine cmdSet quietly ignores some cmds
                 * after VM death, so, it sends it's own errors.
                 */
                outStream_setError(&out, JDWP_ERROR(VM_DEAD));
            } else {
                /* Call the command handler */
                replyToSender = func(&in, &out);
            }

            /* Reply to the sender */
            if (replyToSender) {
                if (inStream_error(&in)) {
                    outStream_setError(&out, inStream_error(&in));
                }
                outStream_sendReply(&out);
            }

            /*
             * Release the resumeLock as the reply has been posted.
             */
            if (resumeCommand(cmd)) {
                debugMonitorExit(resumeLock);
            }

            inStream_destroy(&in);
            outStream_destroy(&out);

            shouldListen = !lastCommand(cmd);
        }
    }
    threadControl_onDisconnect();
    standardHandlers_onDisconnect();

    /*
     * Cut off the transport immediately. This has the effect of
     * cutting off any events that the eventHelper thread might
     * be trying to send.
     */
    transport_close();
    debugMonitorDestroy(cmdQueueLock);

    /* Reset for a new connection to this VM if it's still alive */
    if ( ! gdata->vmDead ) {
        debugInit_reset(getEnv());
    }
}
Esempio n. 9
0
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);
}
Esempio n. 10
0
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);
}