- Timestamp:
- Jun 1, 2010 6:41:10 PM (15 years ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/ConsoleImpl.cpp
r29957 r29965 212 212 Progress *aProgress) 213 213 : VMProgressTask(aConsole, aProgress, false /* aUsesVMPtr */), 214 mSetVMErrorCallback(NULL),215 214 mConfigConstructor(NULL), 216 215 mStartPaused(false), … … 218 217 {} 219 218 220 PFNVMATERROR mSetVMErrorCallback;221 219 PFNCFGMCONSTRUCTOR mConfigConstructor; 222 220 Utf8Str mSavedStateFile; … … 5271 5269 ComAssertComRCRetRC(task->rc()); 5272 5270 5273 task->mSetVMErrorCallback = setVMErrorCallback;5274 5271 task->mConfigConstructor = configConstructor; 5275 5272 task->mSharedFolders = sharedFolders; … … 6871 6868 6872 6869 /** 6873 * VM error callback function. Called by the various VM components. 6874 * 6875 * @param pVM VM handle. Can be NULL if an error occurred before 6876 * successfully creating a VM. 6877 * @param pvUser Pointer to the VMProgressTask structure. 6878 * @param rc VBox status code. 6879 * @param pszFormat Printf-like error message. 6880 * @param args Various number of arguments for the error message. 6881 * 6882 * @thread EMT, VMPowerUp... 6883 * 6884 * @note The VMProgressTask structure modified by this callback is not thread 6885 * safe. 6870 * @copydoc FNVMATERROR 6871 * 6872 * @remarks Might be some tiny serialization concerns with access to the string 6873 * object here... 6886 6874 */ 6887 /* static*/ DECLCALLBACK(void)6888 Console:: setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,6889 const char *pszFormat, va_list args)6890 { 6891 VMProgressTask *task = static_cast<VMProgressTask *>(pvUser);6892 Assert ReturnVoid(task);6893 6894 /* we ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users*/6875 /*static*/ DECLCALLBACK(void) 6876 Console::genericVMSetErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, 6877 const char *pszErrorFmt, va_list va) 6878 { 6879 Utf8Str *pErrorText = (Utf8Str *)pvUser; 6880 AssertPtr(pErrorText); 6881 6882 /* We ignore RT_SRC_POS_DECL arguments to avoid confusion of end-users. */ 6895 6883 va_list va2; 6896 va_copy(va2, args); /* Have to make a copy here or GCC will break. */6897 6898 /* append to the existing error message if any*/6899 if ( task->mErrorMsg.length())6900 task->mErrorMsg = Utf8StrFmt("%s.\n%N (%Rrc)", task->mErrorMsg.raw(),6901 pszFormat, &va2, rc, rc);6884 va_copy(va2, va); 6885 6886 /* Append to any the existing error message. */ 6887 if (pErrorText->length()) 6888 *pErrorText = Utf8StrFmt("%s.\n%N (%Rrc)", pErrorText->c_str(), 6889 pszErrorFmt, &va2, rc, rc); 6902 6890 else 6903 task->mErrorMsg = Utf8StrFmt("%N (%Rrc)", 6904 pszFormat, &va2, rc, rc); 6905 6906 va_end (va2); 6891 *pErrorText = Utf8StrFmt("%N (%Rrc)", pszErrorFmt, &va2, rc, rc); 6892 6893 va_end(va2); 6907 6894 } 6908 6895 … … 7302 7289 alock.leave(); 7303 7290 7304 vrc = VMR3Create(cCpus, task->mSetVMErrorCallback, task.get(),7291 vrc = VMR3Create(cCpus, Console::genericVMSetErrorCallback, &task->mErrorMsg, 7305 7292 task->mConfigConstructor, static_cast<Console *>(console), 7306 7293 &pVM); … … 7451 7438 */ 7452 7439 alock.leave(); 7453 VMR3AtErrorDeregister(pVM, task->mSetVMErrorCallback, task.get());7440 VMR3AtErrorDeregister(pVM, Console::genericVMSetErrorCallback, &task->mErrorMsg); 7454 7441 /** @todo register another VMSetError callback? */ 7455 7442 alock.enter(); -
trunk/src/VBox/Main/ConsoleImplTeleporter.cpp
r29957 r29965 121 121 bool mfLockedMedia; 122 122 int mRc; 123 Utf8Str mErrorText; 123 124 124 125 TeleporterStateTrg(Console *pConsole, PVM pVM, Progress *pProgress, … … 132 133 , mfLockedMedia(false) 133 134 , mRc(VINF_SUCCESS) 135 , mErrorText() 134 136 { 135 137 } … … 219 221 HRESULT 220 222 Console::teleporterSrcReadACK(TeleporterStateSrc *pState, const char *pszWhich, 221 const char *pszNAckMsg /*= NULL*/)222 { 223 char szMsg[ 128];223 const char *pszNAckMsg /*= NULL*/) 224 { 225 char szMsg[256]; 224 226 int vrc = teleporterTcpReadLine(pState, szMsg, sizeof(szMsg)); 225 227 if (RT_FAILURE(vrc)) 226 228 return setError(E_FAIL, tr("Failed reading ACK(%s): %Rrc"), pszWhich, vrc); 227 if (strcmp(szMsg, "ACK")) 228 { 229 if (!strncmp(szMsg, "NACK=", sizeof("NACK=") - 1)) 230 { 231 int32_t vrc2; 232 vrc = RTStrToInt32Full(&szMsg[sizeof("NACK=") - 1], 10, &vrc2); 233 if (vrc == VINF_SUCCESS) 234 { 235 if (pszNAckMsg) 236 { 237 LogRel(("Teleporter: %s: NACK=%Rrc (%d)\n", pszWhich, vrc2, vrc2)); 238 return setError(E_FAIL, pszNAckMsg); 239 } 240 return setError(E_FAIL, "NACK(%s) - %Rrc (%d)", pszWhich, vrc2, vrc2); 241 } 242 } 243 return setError(E_FAIL, tr("%s: Expected ACK or NACK, got '%s'"), pszWhich, szMsg); 244 } 245 return S_OK; 229 230 if (!strcmp(szMsg, "ACK")) 231 return S_OK; 232 233 if (!strncmp(szMsg, "NACK=", sizeof("NACK=") - 1)) 234 { 235 char *pszMsgText = strchr(szMsg, ';'); 236 if (pszMsgText) 237 *pszMsgText++ = '\0'; 238 239 int32_t vrc2; 240 vrc = RTStrToInt32Full(&szMsg[sizeof("NACK=") - 1], 10, &vrc2); 241 if (vrc == VINF_SUCCESS) 242 { 243 /* 244 * Well formed NACK, transform it into an error. 245 */ 246 if (pszNAckMsg) 247 { 248 LogRel(("Teleporter: %s: NACK=%Rrc (%d)\n", pszWhich, vrc2, vrc2)); 249 return setError(E_FAIL, pszNAckMsg); 250 } 251 252 if (pszMsgText) 253 { 254 pszMsgText = RTStrStrip(pszMsgText); 255 for (size_t off = 0; pszMsgText[off]; off++) 256 if (pszMsgText[off] == '\r') 257 pszMsgText[off] = '\n'; 258 259 LogRel(("Teleporter: %s: NACK=%Rrc (%d) - '%s'\n", pszWhich, vrc2, vrc2, pszMsgText)); 260 if (strlen(pszMsgText) > 4) 261 return setError(E_FAIL, "%s", pszMsgText); 262 return setError(E_FAIL, "NACK(%s) - %Rrc (%d) '%s'", pszWhich, vrc2, vrc2, pszMsgText); 263 } 264 265 return setError(E_FAIL, "NACK(%s) - %Rrc (%d)", pszWhich, vrc2, vrc2); 266 } 267 268 if (pszMsgText) 269 pszMsgText[-1] = ';'; 270 } 271 return setError(E_FAIL, tr("%s: Expected ACK or NACK, got '%s'"), pszWhich, szMsg); 246 272 } 247 273 … … 672 698 RTSocketRelease(pState->mhSocket); 673 699 if (RT_FAILURE(vrc)) 700 { 701 if ( vrc == VERR_SSM_CANCELLED 702 && RT_SUCCESS(RTTcpSelectOne(pState->mhSocket, 1))) 703 { 704 hrc = teleporterSrcReadACK(pState, "load-complete"); 705 if (FAILED(hrc)) 706 return hrc; 707 } 674 708 return setError(E_FAIL, tr("VMR3Teleport -> %Rrc"), vrc); 709 } 675 710 676 711 hrc = teleporterSrcReadACK(pState, "load-complete"); … … 1179 1214 1180 1215 1181 static int teleporterTcpWriteNACK(TeleporterStateTrg *pState, int32_t rc2 )1216 static int teleporterTcpWriteNACK(TeleporterStateTrg *pState, int32_t rc2, const char *pszMsgText = NULL) 1182 1217 { 1183 1218 /* … … 1187 1222 teleporterTrgUnlockMedia(pState); 1188 1223 1189 char szMsg[64]; 1190 size_t cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d\n", rc2); 1224 char szMsg[256]; 1225 size_t cch; 1226 if (pszMsgText && *pszMsgText) 1227 { 1228 cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d;%s\n", rc2, pszMsgText); 1229 for (size_t off = 6; off + 1 < cch; off++) 1230 if (szMsg[off] == '\n') 1231 szMsg[off] = '\r'; 1232 } 1233 else 1234 cch = RTStrPrintf(szMsg, sizeof(szMsg), "NACK=%d\n", rc2); 1191 1235 int rc = RTTcpWrite(pState->mhSocket, szMsg, cch); 1192 1236 if (RT_FAILURE(rc)) … … 1288 1332 break; 1289 1333 1334 int vrc2 = VMR3AtErrorRegister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2); 1290 1335 RTSocketRetain(pState->mhSocket); /* For concurrent access by I/O thread and EMT. */ 1291 1336 pState->moffStream = 0; 1337 1292 1338 void *pvUser2 = static_cast<void *>(static_cast<TeleporterState *>(pState)); 1293 1339 vrc = VMR3LoadFromStream(pState->mpVM, &g_teleporterTcpOps, pvUser2, 1294 1340 teleporterProgressCallback, pvUser2); 1341 1295 1342 RTSocketRelease(pState->mhSocket); 1343 vrc2 = VMR3AtErrorDeregister(pState->mpVM, Console::genericVMSetErrorCallback, &pState->mErrorText); AssertRC(vrc2); 1344 1296 1345 if (RT_FAILURE(vrc)) 1297 1346 { 1298 1347 LogRel(("Teleporter: VMR3LoadFromStream -> %Rrc\n", vrc)); 1299 teleporterTcpWriteNACK(pState, vrc );1348 teleporterTcpWriteNACK(pState, vrc, pState->mErrorText.c_str()); 1300 1349 break; 1301 1350 } -
trunk/src/VBox/Main/include/ConsoleImpl.h
r29957 r29965 519 519 static DECLCALLBACK(int) stateProgressCallback(PVM pVM, unsigned uPercent, void *pvUser); 520 520 521 static DECLCALLBACK(void) setVMErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL,522 const char *pszFormat, va_list args);521 static DECLCALLBACK(void) genericVMSetErrorCallback(PVM pVM, void *pvUser, int rc, RT_SRC_POS_DECL, 522 const char *pszErrorFmt, va_list va); 523 523 524 524 static DECLCALLBACK(void) setVMRuntimeErrorCallbackF(PVM pVM, void *pvUser, uint32_t fFatal,
Note:
See TracChangeset
for help on using the changeset viewer.