VirtualBox

Changeset 45006 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Mar 12, 2013 2:58:51 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
84237
Message:

DBGF/DBGC: Fixing power off problems.

Location:
trunk/src/VBox/VMM/VMMR3
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/DBGF.cpp

    r44528 r45006  
    165165{
    166166    PUVM pUVM = pVM->pUVM;
    167     int rc;
    168 
    169     /*
    170      * Send a termination event to any attached debugger.
    171      */
    172     /* wait to become the speaker (we should already be that). */
    173     if (    pVM->dbgf.s.fAttached
    174         &&  RTSemPingShouldWait(&pVM->dbgf.s.PingPong))
    175         RTSemPingWait(&pVM->dbgf.s.PingPong, 5000);
    176 
    177     /* now, send the event if we're the speaker. */
    178     if (    pVM->dbgf.s.fAttached
    179         &&  RTSemPingIsSpeaker(&pVM->dbgf.s.PingPong))
    180     {
    181         DBGFCMD enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_NO_COMMAND);
    182         if (enmCmd == DBGFCMD_DETACH_DEBUGGER)
    183             /* the debugger beat us to initiating the detaching. */
    184             rc = VINF_SUCCESS;
    185         else
    186         {
    187             /* ignore the command (if any). */
    188             enmCmd = DBGFCMD_NO_COMMAND;
    189             pVM->dbgf.s.DbgEvent.enmType = DBGFEVENT_TERMINATING;
    190             pVM->dbgf.s.DbgEvent.enmCtx  = DBGFEVENTCTX_OTHER;
    191             rc = RTSemPing(&pVM->dbgf.s.PingPong);
    192         }
    193 
    194         /*
    195          * Process commands until we get a detached command.
    196          */
    197         while (RT_SUCCESS(rc) && enmCmd != DBGFCMD_DETACHED_DEBUGGER)
    198         {
    199             if (enmCmd != DBGFCMD_NO_COMMAND)
    200             {
    201                 /* process command */
    202                 bool fResumeExecution;
    203                 DBGFCMDDATA CmdData = pVM->dbgf.s.VMMCmdData;
    204                 rc = dbgfR3VMMCmd(pVM, enmCmd, &CmdData, &fResumeExecution);
    205                 enmCmd = DBGFCMD_NO_COMMAND;
    206             }
    207             else
    208             {
    209                 /* wait for new command. */
    210                 rc = RTSemPingWait(&pVM->dbgf.s.PingPong, RT_INDEFINITE_WAIT);
    211                 if (RT_SUCCESS(rc))
    212                     enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_NO_COMMAND);
    213             }
    214         }
    215     }
    216 
    217     /*
    218      * Terminate the other bits.
    219      */
     167
    220168    dbgfR3OSTerm(pUVM);
    221169    dbgfR3AsTerm(pUVM);
     
    223171    dbgfR3TraceTerm(pVM);
    224172    dbgfR3InfoTerm(pUVM);
     173
    225174    return VINF_SUCCESS;
     175}
     176
     177
     178/**
     179 * Called when the VM is powered off to detach debuggers.
     180 *
     181 * @param   pVM     The VM handle.
     182 */
     183VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM)
     184{
     185
     186    /*
     187     * Send a termination event to any attached debugger.
     188     */
     189    /* wait to become the speaker (we should already be that). */
     190    if (    pVM->dbgf.s.fAttached
     191        &&  RTSemPingShouldWait(&pVM->dbgf.s.PingPong))
     192        RTSemPingWait(&pVM->dbgf.s.PingPong, 5000);
     193
     194    if (pVM->dbgf.s.fAttached)
     195    {
     196        /* Just mark it as detached if we're not in a position to send a power
     197           off event.  It should fail later on. */
     198        if (!RTSemPingIsSpeaker(&pVM->dbgf.s.PingPong))
     199        {
     200            ASMAtomicWriteBool(&pVM->dbgf.s.fAttached, false);
     201            if (RTSemPingIsSpeaker(&pVM->dbgf.s.PingPong))
     202                ASMAtomicWriteBool(&pVM->dbgf.s.fAttached, true);
     203        }
     204
     205        if (RTSemPingIsSpeaker(&pVM->dbgf.s.PingPong))
     206        {
     207            /* Try send the power off event. */
     208            int rc;
     209            DBGFCMD enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_NO_COMMAND);
     210            if (enmCmd == DBGFCMD_DETACH_DEBUGGER)
     211                /* the debugger beat us to initiating the detaching. */
     212                rc = VINF_SUCCESS;
     213            else
     214            {
     215                /* ignore the command (if any). */
     216                enmCmd = DBGFCMD_NO_COMMAND;
     217                pVM->dbgf.s.DbgEvent.enmType = DBGFEVENT_POWERING_OFF;
     218                pVM->dbgf.s.DbgEvent.enmCtx  = DBGFEVENTCTX_OTHER;
     219                rc = RTSemPing(&pVM->dbgf.s.PingPong);
     220            }
     221
     222            /*
     223             * Process commands and priority requests until we get a command
     224             * indicating that the debugger has detached.
     225             */
     226            uint32_t cPollHack = 1;
     227            PVMCPU   pVCpu     = VMMGetCpu(pVM);
     228            while (RT_SUCCESS(rc))
     229            {
     230                if (enmCmd != DBGFCMD_NO_COMMAND)
     231                {
     232                    /* process command */
     233                    bool fResumeExecution;
     234                    DBGFCMDDATA CmdData = pVM->dbgf.s.VMMCmdData;
     235                    rc = dbgfR3VMMCmd(pVM, enmCmd, &CmdData, &fResumeExecution);
     236                    if (enmCmd == DBGFCMD_DETACHED_DEBUGGER)
     237                        break;
     238                    enmCmd = DBGFCMD_NO_COMMAND;
     239                }
     240                else
     241                {
     242                    /* Wait for new command, processing pending priority requests
     243                       first.  The request processing is a bit crazy, but
     244                       unfortunately required by plugin unloading. */
     245                    if (   VM_FF_ISPENDING(pVM, VM_FF_REQUEST)
     246                        || VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_REQUEST))
     247                    {
     248                        LogFlow(("DBGFR3PowerOff: Processes priority requests...\n"));
     249                        rc = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY, true /*fPriorityOnly*/);
     250                        if (rc == VINF_SUCCESS)
     251                            rc = VMR3ReqProcessU(pVM->pUVM, pVCpu->idCpu, true /*fPriorityOnly*/);
     252                        LogFlow(("DBGFR3PowerOff: VMR3ReqProcess -> %Rrc\n", rc));
     253                        cPollHack = 1;
     254                    }
     255                    else if (cPollHack < 120)
     256                        cPollHack++;
     257
     258                    rc = RTSemPingWait(&pVM->dbgf.s.PingPong, cPollHack);
     259                    if (RT_SUCCESS(rc))
     260                        enmCmd = dbgfR3SetCmd(pVM, DBGFCMD_NO_COMMAND);
     261                    else if (rc == VERR_TIMEOUT)
     262                        rc = VINF_SUCCESS;
     263                }
     264            }
     265
     266            /*
     267             * Clear the FF so we won't get confused later on.
     268             */
     269            VM_FF_CLEAR(pVM, VM_FF_DBGF);
     270        }
     271    }
    226272}
    227273
     
    869915VMMR3DECL(int) DBGFR3Attach(PUVM pUVM)
    870916{
    871     UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
     917    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    872918    PVM pVM = pUVM->pVM;
    873     VM_ASSERT_VALID_EXT_RETURN(pVM, false);
     919    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    874920
    875921    /*
     
    925971     * Check if attached.
    926972     */
    927     UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
     973    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    928974    PVM pVM = pUVM->pVM;
    929     VM_ASSERT_VALID_EXT_RETURN(pVM, false);
     975    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    930976    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);
    931977
     
    9731019     * Check state.
    9741020     */
    975     UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
     1021    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    9761022    PVM pVM = pUVM->pVM;
    977     VM_ASSERT_VALID_EXT_RETURN(pVM, false);
     1023    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    9781024    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);
    9791025    *ppEvent = NULL;
     
    10081054     * Check state.
    10091055     */
    1010     UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
     1056    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
    10111057    PVM pVM = pUVM->pVM;
    1012     VM_ASSERT_VALID_EXT_RETURN(pVM, false);
     1058    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
    10131059    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);
    10141060    RTPINGPONGSPEAKER enmSpeaker = pVM->dbgf.s.PingPong.enmSpeaker;
     
    10511097 * This function is only used by lazy, multiplexing debuggers. :-)
    10521098 *
    1053  * @returns True if waitable.
    1054  * @returns False if not waitable.
     1099 * @returns VBox status code.
     1100 * @retval  VINF_SUCCESS if waitable.
     1101 * @retval  VERR_SEM_OUT_OF_TURN if not waitable.
     1102 * @retval  VERR_INVALID_VM_HANDLE if the VM is being (/ has been) destroyed
     1103 *          (not asserted) or if the handle is invalid (asserted).
     1104 * @retval  VERR_DBGF_NOT_ATTACHED if not attached.
     1105 *
    10551106 * @param   pUVM        The user mode VM handle.
    10561107 */
    1057 VMMR3DECL(bool) DBGFR3CanWait(PUVM pUVM)
    1058 {
    1059     UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);
     1108VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM)
     1109{
     1110    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
     1111
     1112    /* Note! There is a slight race here, unfortunately. */
    10601113    PVM pVM = pUVM->pVM;
    1061     VM_ASSERT_VALID_EXT_RETURN(pVM, false);
    1062     AssertReturn(pVM->dbgf.s.fAttached, false);
    1063 
    1064     return RTSemPongShouldWait(&pVM->dbgf.s.PingPong);
     1114    if (!RT_VALID_PTR(pVM))
     1115        return VERR_INVALID_VM_HANDLE;
     1116    if (pVM->enmVMState >= VMSTATE_DESTROYING)
     1117        return VERR_INVALID_VM_HANDLE;
     1118    AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED);
     1119
     1120    if (!RTSemPongShouldWait(&pVM->dbgf.s.PingPong))
     1121        return VERR_SEM_OUT_OF_TURN;
     1122
     1123    return VINF_SUCCESS;
    10651124}
    10661125
  • trunk/src/VBox/VMM/VMMR3/VM.cpp

    r44730 r45006  
    22572257         */
    22582258        PDMR3PowerOff(pVM);
     2259        DBGFR3PowerOff(pVM);
    22592260
    22602261        PUVM pUVM = pVM->pUVM;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette