Changeset 45006 in vbox
- Timestamp:
- Mar 12, 2013 2:58:51 PM (12 years ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/dbgf.h
r44896 r45006 180 180 */ 181 181 DBGFEVENT_DEV_STOP, 182 /** The VM is terminating.182 /** The VM is powering off. 183 183 * When this notification is received, the debugger thread should detach ASAP. 184 184 */ 185 DBGFEVENT_ TERMINATING,185 DBGFEVENT_POWERING_OFF, 186 186 187 187 /** The usual 32-bit hack. */ … … 284 284 VMMR3_INT_DECL(int) DBGFR3Init(PVM pVM); 285 285 VMMR3_INT_DECL(int) DBGFR3Term(PVM pVM); 286 VMMR3_INT_DECL(void) DBGFR3PowerOff(PVM pVM); 286 287 VMMR3_INT_DECL(void) DBGFR3Relocate(PVM pVM, RTGCINTPTR offDelta); 287 288 VMMR3_INT_DECL(int) DBGFR3VMMForcedAction(PVM pVM); … … 300 301 VMMR3DECL(int) DBGFR3Halt(PUVM pUVM); 301 302 VMMR3DECL(bool) DBGFR3IsHalted(PUVM pUVM); 302 VMMR3DECL( bool) DBGFR3CanWait(PUVM pUVM);303 VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM); 303 304 VMMR3DECL(int) DBGFR3Resume(PUVM pUVM); 304 305 VMMR3DECL(int) DBGFR3Step(PUVM pUVM, VMCPUID idCpu); -
trunk/src/VBox/Debugger/DBGConsole.cpp
r44399 r45006 738 738 } 739 739 740 case DBGFEVENT_ TERMINATING:740 case DBGFEVENT_POWERING_OFF: 741 741 { 742 742 pDbgc->fReady = false; 743 743 pDbgc->pBack->pfnSetReady(pDbgc->pBack, false); 744 pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\nVM is terminating!\n");744 pDbgc->CmdHlp.pfnPrintf(&pDbgc->CmdHlp, NULL, "\nVM is powering off!\n"); 745 745 fPrintPrompt = false; 746 746 rc = VERR_GENERAL_FAILURE; … … 808 808 * before we must flush the log. 809 809 */ 810 int rc = VINF_SUCCESS;810 int rc; 811 811 for (;;) 812 812 { 813 if ( pDbgc->pUVM 814 && DBGFR3CanWait(pDbgc->pUVM)) 813 rc = VERR_SEM_OUT_OF_TURN; 814 if (pDbgc->pUVM) 815 rc = DBGFR3QueryWaitable(pDbgc->pUVM); 816 817 if (RT_SUCCESS(rc)) 815 818 { 816 819 /* … … 838 841 } 839 842 } 840 else 843 else if (rc == VERR_SEM_OUT_OF_TURN) 841 844 { 842 845 /* … … 850 853 } 851 854 } 855 else 856 break; 852 857 853 858 /* -
trunk/src/VBox/Debugger/testcase/tstDBGCStubs.cpp
r44528 r45006 81 81 return VERR_INTERNAL_ERROR; 82 82 } 83 VMMR3DECL( bool) DBGFR3CanWait(PUVM pUVM)84 { 85 return true;83 VMMR3DECL(int) DBGFR3QueryWaitable(PUVM pUVM) 84 { 85 return VINF_SUCCESS; 86 86 } 87 87 VMMR3DECL(int) DBGFR3Detach(PUVM pUVM) -
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.