Changeset 45006 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Mar 12, 2013 2:58:51 PM (12 years ago)
- svn:sync-xref-src-repo-rev:
- 84237
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/DBGF.cpp
r44528 r45006 165 165 { 166 166 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 220 168 dbgfR3OSTerm(pUVM); 221 169 dbgfR3AsTerm(pUVM); … … 223 171 dbgfR3TraceTerm(pVM); 224 172 dbgfR3InfoTerm(pUVM); 173 225 174 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 */ 183 VMMR3_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 } 226 272 } 227 273 … … 869 915 VMMR3DECL(int) DBGFR3Attach(PUVM pUVM) 870 916 { 871 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);917 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 872 918 PVM pVM = pUVM->pVM; 873 VM_ASSERT_VALID_EXT_RETURN(pVM, false);919 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 874 920 875 921 /* … … 925 971 * Check if attached. 926 972 */ 927 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);973 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 928 974 PVM pVM = pUVM->pVM; 929 VM_ASSERT_VALID_EXT_RETURN(pVM, false);975 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 930 976 AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED); 931 977 … … 973 1019 * Check state. 974 1020 */ 975 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);1021 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 976 1022 PVM pVM = pUVM->pVM; 977 VM_ASSERT_VALID_EXT_RETURN(pVM, false);1023 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 978 1024 AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED); 979 1025 *ppEvent = NULL; … … 1008 1054 * Check state. 1009 1055 */ 1010 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false);1056 UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE); 1011 1057 PVM pVM = pUVM->pVM; 1012 VM_ASSERT_VALID_EXT_RETURN(pVM, false);1058 VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE); 1013 1059 AssertReturn(pVM->dbgf.s.fAttached, VERR_DBGF_NOT_ATTACHED); 1014 1060 RTPINGPONGSPEAKER enmSpeaker = pVM->dbgf.s.PingPong.enmSpeaker; … … 1051 1097 * This function is only used by lazy, multiplexing debuggers. :-) 1052 1098 * 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 * 1055 1106 * @param pUVM The user mode VM handle. 1056 1107 */ 1057 VMMR3DECL(bool) DBGFR3CanWait(PUVM pUVM) 1058 { 1059 UVM_ASSERT_VALID_EXT_RETURN(pUVM, false); 1108 VMMR3DECL(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. */ 1060 1113 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; 1065 1124 } 1066 1125 -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r44730 r45006 2257 2257 */ 2258 2258 PDMR3PowerOff(pVM); 2259 DBGFR3PowerOff(pVM); 2259 2260 2260 2261 PUVM pUVM = pVM->pUVM;
Note:
See TracChangeset
for help on using the changeset viewer.