Example #1
0
/**
 * Resumes VM execution.
 *
 * There is no receipt event on this command.
 *
 * @returns VBox status.
 * @param   pVM     Pointer to the VM.
 */
VMMR3DECL(int) DBGFR3Resume(PVM pVM)
{
    /*
     * Check state.
     */
    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);
    AssertReturn(RTSemPongIsSpeaker(&pVM->dbgf.s.PingPong), VERR_SEM_OUT_OF_TURN);

    /*
     * Send the ping back to the emulation thread telling it to run.
     */
    dbgfR3SetCmd(pVM, DBGFCMD_GO);
    int rc = RTSemPong(&pVM->dbgf.s.PingPong);
    AssertRC(rc);

    return rc;
}
Example #2
0
/**
 * Step Into.
 *
 * A single step event is generated from this command.
 * The current implementation is not reliable, so don't rely on the event coming.
 *
 * @returns VBox status.
 * @param   pVM     Pointer to the VM.
 * @param   idCpu   The ID of the CPU to single step on.
 */
VMMR3DECL(int) DBGFR3Step(PVM pVM, VMCPUID idCpu)
{
    /*
     * Check state.
     */
    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);
    AssertReturn(RTSemPongIsSpeaker(&pVM->dbgf.s.PingPong), VERR_SEM_OUT_OF_TURN);
    AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_PARAMETER);

    /*
     * Send the ping back to the emulation thread telling it to run.
     */
/** @todo SMP (idCpu) */
    dbgfR3SetCmd(pVM, DBGFCMD_SINGLE_STEP);
    int rc = RTSemPong(&pVM->dbgf.s.PingPong);
    AssertRC(rc);
    return rc;
}
Example #3
0
/**
 * Detaches a debugger from the specified VM.
 *
 * Caller must be attached to the VM.
 *
 * @returns VBox status code.
 * @param   pVM     Pointer to the VM.
 */
VMMR3DECL(int) DBGFR3Detach(PVM pVM)
{
    LogFlow(("DBGFR3Detach:\n"));
    int rc;

    /*
     * Check if attached.
     */
    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);

    /*
     * Try send the detach command.
     * Keep in mind that we might be racing EMT, so, be extra careful.
     */
    DBGFCMD enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_DETACH_DEBUGGER);
    if (RTSemPongIsSpeaker(&pVM->dbgf.s.PingPong))
    {
        rc = RTSemPong(&pVM->dbgf.s.PingPong);
        AssertMsgRCReturn(rc, ("Failed to signal emulation thread. rc=%Rrc\n", rc), rc);
        LogRel(("DBGFR3Detach: enmCmd=%d (pong -> ping)\n", enmCmd));
    }

    /*
     * Wait for the OK event.
     */
    rc = RTSemPongWait(&pVM->dbgf.s.PingPong, RT_INDEFINITE_WAIT);
    AssertLogRelMsgRCReturn(rc, ("Wait on detach command failed, rc=%Rrc\n", rc), rc);

    /*
     * Send the notification command indicating that we're really done.
     */
    enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_DETACHED_DEBUGGER);
    rc = RTSemPong(&pVM->dbgf.s.PingPong);
    AssertMsgRCReturn(rc, ("Failed to signal emulation thread. rc=%Rrc\n", rc), rc);

    LogFlowFunc(("returns VINF_SUCCESS\n"));
    return VINF_SUCCESS;
}
static DECLCALLBACK(int) tstSemPingPongThread(RTTHREAD hThread, void *pvPP)
{
    int rc;
    PRTPINGPONG pPP = (PRTPINGPONG)pvPP;
    for (uint32_t i = 0; i < TSTSEMPINGPONG_ITERATIONS; i++)
    {
        if (!RTSemPongShouldWait(pPP))
        {
            ASMAtomicIncU32(&g_cErrors);
            RTPrintf("tstSemPingPong: ERROR - RTSemPongShouldWait returned false before RTSemPongWait.\n");
        }

        rc = RTSemPongWait(pPP, RT_INDEFINITE_WAIT);
        if (RT_FAILURE(rc))
        {
            ASMAtomicIncU32(&g_cErrors);
            RTPrintf("tstSemPingPong: ERROR - RTSemPongWait -> %Rrc\n", rc);
            break;
        }

        if (!RTSemPongIsSpeaker(pPP))
        {
            ASMAtomicIncU32(&g_cErrors);
            RTPrintf("tstSemPingPong: ERROR - RTSemPongIsSpeaker returned false before RTSemPong.\n");
        }

        rc = RTSemPong(pPP);
        if (RT_FAILURE(rc))
        {
            ASMAtomicIncU32(&g_cErrors);
            RTPrintf("tstSemPingPong: ERROR - RTSemPong -> %Rrc\n", rc);
            break;
        }
    }
    return rc;
}