/**
 * Releases the instance data.
 *
 * @param   pThis               The instance data.
 */
static void rtDbgModDeferredReleaseInstanceData(PRTDBGMODDEFERRED pThis)
{
    AssertPtr(pThis);
    uint32_t cRefs = ASMAtomicDecU32(&pThis->cRefs); Assert(cRefs < 8);
    if (!cRefs)
    {
        RTDbgCfgRelease(pThis->hDbgCfg);
        pThis->hDbgCfg = NIL_RTDBGCFG;
        RTMemFree(pThis);
    }
}
Пример #2
0
/**
 * Make a console instance.
 *
 * This will not return until either an 'exit' command is issued or a error code
 * indicating connection loss is encountered.
 *
 * @returns VINF_SUCCESS if console termination caused by the 'exit' command.
 * @returns The VBox status code causing the console termination.
 *
 * @param   pUVM        The user mode VM handle.
 * @param   pBack       Pointer to the backend structure. This must contain
 *                      a full set of function pointers to service the console.
 * @param   fFlags      Reserved, must be zero.
 * @remarks A forced termination of the console is easiest done by forcing the
 *          callbacks to return fatal failures.
 */
DBGDECL(int) DBGCCreate(PUVM pUVM, PDBGCBACK pBack, unsigned fFlags)
{
    /*
     * Validate input.
     */
    AssertPtrNullReturn(pUVM, VERR_INVALID_VM_HANDLE);
    PVM pVM = NULL;
    if (pUVM)
    {
        pVM = VMR3GetVM(pUVM);
        AssertPtrReturn(pVM, VERR_INVALID_VM_HANDLE);
    }

    /*
     * Allocate and initialize instance data
     */
    PDBGC pDbgc;
    int rc = dbgcCreate(&pDbgc, pBack, fFlags);
    if (RT_FAILURE(rc))
        return rc;
    if (!HMR3IsEnabled(pUVM))
        pDbgc->hDbgAs = DBGF_AS_RC_AND_GC_GLOBAL;

    /*
     * Print welcome message.
     */
    rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
                                 "Welcome to the VirtualBox Debugger!\n");

    /*
     * Attach to the specified VM.
     */
    if (RT_SUCCESS(rc) && pUVM)
    {
        rc = dbgcReadConfig(pDbgc, pUVM);
        if (RT_SUCCESS(rc))
        {
            rc = DBGFR3Attach(pUVM);
            if (RT_SUCCESS(rc))
            {
                pDbgc->pVM   = pVM;
                pDbgc->pUVM  = pUVM;
                pDbgc->idCpu = 0;
                rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL,
                                             "Current VM is %08x, CPU #%u\n" /** @todo get and print the VM name! */
                                             , pDbgc->pVM, pDbgc->idCpu);
            }
            else
                rc = pDbgc->CmdHlp.pfnVBoxError(&pDbgc->CmdHlp, rc, "When trying to attach to VM %p\n", pDbgc->pVM);
        }
        else
            rc = pDbgc->CmdHlp.pfnVBoxError(&pDbgc->CmdHlp, rc, "Error reading configuration\n");
    }

    /*
     * Load plugins.
     */
    if (RT_SUCCESS(rc))
    {
        if (pVM)
            DBGFR3PlugInLoadAll(pDbgc->pUVM);
        dbgcEventInit(pDbgc);
        dbgcRunInitScripts(pDbgc);

        rc = pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "VBoxDbg> ");
        if (RT_SUCCESS(rc))
        {
            /*
             * Set debug config log callback.
             */
            RTDBGCFG    hDbgCfg = DBGFR3AsGetConfig(pUVM);
            if (   hDbgCfg != NIL_RTDBGCFG
                && RTDbgCfgRetain(hDbgCfg) != UINT32_MAX)
            {
                int rc2 = RTDbgCfgSetLogCallback(hDbgCfg, dbgcDbgCfgLogCallback, pDbgc);
                if (RT_FAILURE(rc2))
                {
                    hDbgCfg = NIL_RTDBGCFG;
                    RTDbgCfgRelease(hDbgCfg);
                }
            }
            else
                hDbgCfg = NIL_RTDBGCFG;


            /*
             * Run the debugger main loop.
             */
            rc = dbgcRun(pDbgc);


            /*
             * Remove debug config log callback.
             */
            if (hDbgCfg != NIL_RTDBGCFG)
            {
                RTDbgCfgSetLogCallback(hDbgCfg, NULL, NULL);
                RTDbgCfgRelease(hDbgCfg);
            }
        }
        dbgcEventTerm(pDbgc);
    }
    else
        pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\nDBGCCreate error: %Rrc\n", rc);


    /*
     * Cleanup console debugger session.
     */
    dbgcDestroy(pDbgc);
    return rc == VERR_DBGC_QUIT ? VINF_SUCCESS : rc;
}