Пример #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)); */
}
Пример #2
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);
}
Пример #3
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());
    }
}