/** * Create a new thread. * * Same as RTThreadCreate except the name is given in the RTStrPrintfV form. * * @returns iprt status code. * @param pThread See RTThreadCreate. * @param pfnThread See RTThreadCreate. * @param pvUser See RTThreadCreate. * @param cbStack See RTThreadCreate. * @param enmType See RTThreadCreate. * @param fFlags See RTThreadCreate. * @param pszNameFmt Thread name format. * @param va Format arguments. */ RTDECL(int) RTThreadCreateV(PRTTHREAD pThread, PFNRTTHREAD pfnThread, void *pvUser, size_t cbStack, RTTHREADTYPE enmType, uint32_t fFlags, const char *pszNameFmt, va_list va) { char szName[RTTHREAD_NAME_LEN * 2]; RTStrPrintfV(szName, sizeof(szName), pszNameFmt, va); return RTThreadCreate(pThread, pfnThread, pvUser, cbStack, enmType, fFlags, szName); }
/** * The function PassVA and PassVA2 calls. */ static DECLCALLBACK(int) PassVACallback(PUVM pUVM, unsigned u4K, unsigned u1G, const char *pszFormat, va_list *pva) { NOREF(pUVM); if (u4K != _4K) { RTPrintf(TESTCASE ": u4K=%#x!\n", u4K); g_cErrors++; } if (u1G != _1G) { RTPrintf(TESTCASE ": u1G=%#x!\n", u1G); g_cErrors++; } if (strcmp(pszFormat, "hello %s")) { RTPrintf(TESTCASE ": pszFormat=%p:{%s}!\n", pszFormat, pszFormat); g_cErrors++; } char szBuf[1024]; RTStrPrintfV(szBuf, sizeof(szBuf), pszFormat, *pva); if (strcmp(szBuf, "hello world")) { RTPrintf(TESTCASE ": RTStrPrintfV -> '%s'!\n", szBuf); g_cErrors++; } return VINF_SUCCESS; }
/** * RTStrPrintfv wrapper. * * @param pszError The error buffer. * @param cbError The size of the buffer. * @param pszFormat The error message format string. * @param ... Format arguments. */ static void vboxExtPackSetError(char *pszError, size_t cbError, const char *pszFormat, ...) { va_list va; va_start(va, pszFormat); RTStrPrintfV(pszError, cbError, pszFormat, va); va_end(va); }
/** * Send a debugger event which takes the full source file location. * * @returns VBox status. * @param pVM Pointer to the VM. * @param enmEvent The event to send. * @param pszFile Source file. * @param uLine Line number in source file. * @param pszFunction Function name. * @param pszFormat Message which accompanies the event. * @param args Message arguments. */ VMMR3DECL(int) DBGFR3EventSrcV(PVM pVM, DBGFEVENTTYPE enmEvent, const char *pszFile, unsigned uLine, const char *pszFunction, const char *pszFormat, va_list args) { int rc = dbgfR3EventPrologue(pVM, enmEvent); if (RT_FAILURE(rc)) return rc; /* * Format the message. */ char *pszMessage = NULL; char szMessage[8192]; if (pszFormat && *pszFormat) { pszMessage = &szMessage[0]; RTStrPrintfV(szMessage, sizeof(szMessage), pszFormat, args); } /* * Send the event and process the reply communication. */ pVM->dbgf.s.DbgEvent.enmType = enmEvent; pVM->dbgf.s.DbgEvent.enmCtx = dbgfR3FigureEventCtx(pVM); pVM->dbgf.s.DbgEvent.u.Src.pszFile = pszFile; pVM->dbgf.s.DbgEvent.u.Src.uLine = uLine; pVM->dbgf.s.DbgEvent.u.Src.pszFunction = pszFunction; pVM->dbgf.s.DbgEvent.u.Src.pszMessage = pszMessage; return dbgfR3SendEvent(pVM); }
/** * Testings va_list passing in VMSetRuntimeError. */ static DECLCALLBACK(void) MyAtRuntimeError(PUVM pUVM, void *pvUser, uint32_t fFlags, const char *pszErrorId, const char *pszFormat, va_list va) { NOREF(pUVM); if (strcmp((const char *)pvUser, "user argument")) { RTPrintf(TESTCASE ": pvUser=%p:{%s}!\n", pvUser, (const char *)pvUser); g_cErrors++; } if (fFlags) { RTPrintf(TESTCASE ": fFlags=%#x!\n", fFlags); g_cErrors++; } if (strcmp(pszErrorId, "enum")) { RTPrintf(TESTCASE ": pszErrorId=%p:{%s}!\n", pszErrorId, pszErrorId); g_cErrors++; } if (strcmp(pszFormat, "some %s string")) { RTPrintf(TESTCASE ": pszFormat=%p:{%s}!\n", pszFormat, pszFormat); g_cErrors++; } char szBuf[1024]; RTStrPrintfV(szBuf, sizeof(szBuf), pszFormat, va); if (strcmp(szBuf, "some error string")) { RTPrintf(TESTCASE ": RTStrPrintfV -> '%s'!\n", szBuf); g_cErrors++; } }
/** * RTStrPrintfv wrapper. * * @returns @a rc * @param rc The status code to return. * @param pszError The error buffer. * @param cbError The size of the buffer. * @param pszFormat The error message format string. * @param ... Format arguments. */ static int vboxExtPackReturnError(int rc, char *pszError, size_t cbError, const char *pszFormat, ...) { va_list va; va_start(va, pszFormat); RTStrPrintfV(pszError, cbError, pszFormat, va); va_end(va); return rc; }
RTR3DECL(int) RTFileOpenV(PRTFILE pFile, uint64_t fOpen, const char *pszFilenameFmt, va_list va) { char szFilename[RTPATH_MAX]; size_t cchFilename = RTStrPrintfV(szFilename, sizeof(szFilename), pszFilenameFmt, va); if (cchFilename >= sizeof(szFilename) - 1) return VERR_FILENAME_TOO_LONG; return RTFileOpen(pFile, szFilename, fOpen); }
DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va) { char szMsg[256]; RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va); szMsg[sizeof(szMsg) - 1] = '\0'; DbgPrint("%s", szMsg); NOREF(fInitial); }
// A helper for the various logging routines. static void VLogF(const char *methodName, const char *fmt, va_list argptr) { char buff[512]; #ifdef VBOX /* Enable the use of VBox formatting types. */ RTStrPrintfV(buff, sizeof(buff), fmt, argptr); #else // Use safer NS_ functions. PR_vsnprintf(buff, sizeof(buff), fmt, argptr); #endif LogMessage(methodName, buff); }
extern "C" DECLEXPORT(void) TrustedError(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va) { # ifdef RT_OS_DARWIN ShutUpAppKit(); # endif /* RT_OS_DARWIN */ /* We have to create QApplication anyway just to show the only one error-message. * This is a bit hackish as we don't have the argument vector handy. */ int argc = 0; char *argv[2] = { NULL, NULL }; QApplication a(argc, &argv[0]); /* Prepare the error-message: */ QString strTitle = QApplication::tr("VirtualBox - Error In %1").arg(pszWhere); char szMsgBuf[1024]; RTStrPrintfV(szMsgBuf, sizeof(szMsgBuf), pszMsgFmt, va); QString strText = QApplication::tr("<html><b>%1 (rc=%2)</b><br/><br/>").arg(szMsgBuf).arg(rc); strText.replace(QString("\n"), QString("<br>")); switch (enmWhat) { case kSupInitOp_Driver: # ifdef RT_OS_LINUX strText += g_QStrHintLinuxNoDriver; # else /* RT_OS_LINUX */ strText += g_QStrHintOtherNoDriver; # endif /* !RT_OS_LINUX */ break; # ifdef RT_OS_LINUX case kSupInitOp_IPRT: case kSupInitOp_Misc: if (rc == VERR_NO_MEMORY) strText += g_QStrHintLinuxNoMemory; else # endif /* RT_OS_LINUX */ if (rc == VERR_VM_DRIVER_VERSION_MISMATCH) # ifdef RT_OS_LINUX strText += g_QStrHintLinuxWrongDriverVersion; # else /* RT_OS_LINUX */ strText += g_QStrHintOtherWrongDriverVersion; # endif /* !RT_OS_LINUX */ else strText += g_QStrHintReinstall; break; case kSupInitOp_Integrity: case kSupInitOp_RootCheck: strText += g_QStrHintReinstall; break; default: /* no hints here */ break; }
DECLHIDDEN(void) rtR0AssertNativeMsg2V(bool fInitial, const char *pszFormat, va_list va) { char szMsg[256]; IPRT_LINUX_SAVE_EFL_AC(); RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va); szMsg[sizeof(szMsg) - 1] = '\0'; printk(KERN_EMERG "%s", szMsg); NOREF(fInitial); IPRT_LINUX_RESTORE_EFL_AC(); }
/** * Alternative version of SUPR0Printf for Windows. * * @returns 0. * @param pszFormat The format string. */ SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...) { va_list va; char szMsg[512]; va_start(va, pszFormat); size_t cch = RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va); szMsg[sizeof(szMsg) - 1] = '\0'; va_end(va); RTLogWriteDebugger(szMsg, cch); return 0; }
RTDECL(int) RTMsgSetProgName(const char *pszFormat, ...) { g_pszProgName = &g_szrtProcExePath[g_offrtProcName]; va_list va; va_start(va, pszFormat); RTStrPrintfV(g_szProgName, sizeof(g_szProgName) - 1, pszFormat, va); va_end(va); g_pszProgName = g_szProgName; return VINF_SUCCESS; }
RTDECL(int) SUPR0Printf(const char *pszFormat, ...) { va_list args; char szMsg[512]; va_start(args, pszFormat); RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, args); va_end(args); szMsg[sizeof(szMsg) - 1] = '\0'; cmn_err(CE_CONT, "%s", szMsg); return 0; }
RTDECL(int) SUPR0Printf(const char *pszFormat, ...) { va_list va; char szMsg[512]; va_start(va, pszFormat); RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, va); va_end(va); szMsg[sizeof(szMsg) - 1] = '\0'; printk("%s", szMsg); return 0; }
RTDECL(int) RTErrInfoSetV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va) { if (pErrInfo) { AssertPtr(pErrInfo); Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); RTStrPrintfV(pErrInfo->pszMsg, pErrInfo->cbMsg, pszFormat, va); pErrInfo->rc = rc; pErrInfo->fFlags |= RTERRINFO_FLAGS_SET; } return rc; }
/** * Opens a file stream. * * @returns iprt status code. * @param pszMode The open mode. See fopen() standard. * Format: <a|r|w>[+][b|t] * @param ppStream Where to store the opened stream. * @param pszFilenameFmt Filename path format string. * @param args Arguments to the format string. */ RTR3DECL(int) RTStrmOpenFV(const char *pszMode, PRTSTREAM *ppStream, const char *pszFilenameFmt, va_list args) { int rc; char szFilename[RTPATH_MAX]; size_t cch = RTStrPrintfV(szFilename, sizeof(szFilename), pszFilenameFmt, args); if (cch < sizeof(szFilename)) rc = RTStrmOpen(szFilename, pszMode, ppStream); else { AssertMsgFailed(("The filename is too long cch=%d\n", cch)); rc = VERR_FILENAME_TOO_LONG; } return rc; }
SUPR0DECL(int) SUPR0Printf(const char *pszFormat, ...) { va_list va; char szMsg[256]; int cch; va_start(va, pszFormat); cch = RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, va); va_end(va); printf("%s", szMsg); return cch; }
RTDECL(int) SUPR0Printf(const char *pszFormat, ...) { va_list args; char szMsg[512]; /* cmn_err() acquires adaptive mutexes. Not preemption safe, see @bugref{6657}. */ if (!RTThreadPreemptIsEnabled(NIL_RTTHREAD)) return 0; va_start(args, pszFormat); RTStrPrintfV(szMsg, sizeof(szMsg) - 1, pszFormat, args); va_end(args); szMsg[sizeof(szMsg) - 1] = '\0'; cmn_err(CE_CONT, "%s", szMsg); return 0; }
/*PRINTFLIKE2*/ void ctf_decl_sprintf(ctf_decl_t *cd, const char *format, ...) { size_t len = (size_t)(cd->cd_end - cd->cd_ptr); va_list ap; size_t n; va_start(ap, format); #ifndef VBOX n = vsnprintf(cd->cd_ptr, len, format, ap); #else n = RTStrPrintfV(cd->cd_ptr, len, format, ap); #endif va_end(ap); cd->cd_ptr += MIN(n, len); cd->cd_len += n; }
RTDECL(int) RTErrInfoAddV(PRTERRINFO pErrInfo, int rc, const char *pszFormat, va_list va) { if (pErrInfo) { AssertPtr(pErrInfo); Assert((pErrInfo->fFlags & RTERRINFO_FLAGS_MAGIC_MASK) == RTERRINFO_FLAGS_MAGIC); if (pErrInfo->fFlags & RTERRINFO_FLAGS_SET) { char *pszOut = (char *)memchr(pErrInfo->pszMsg, '\0', pErrInfo->cbMsg - 2); if (pszOut) RTStrPrintfV(pszOut, &pErrInfo->pszMsg[pErrInfo->cbMsg] - pszOut, pszFormat, va); } else { while (*pszFormat == ' ') pszFormat++; return RTErrInfoSetV(pErrInfo, rc, pszFormat, va); } } return rc; }
/** * Constructs the path of a sysfs file from the format parameters passed, * prepending a prefix if the path is relative. * * @returns The number of characters returned, or -1 and errno set to ERANGE on * failure. * * @param pszPrefix The prefix to prepend if the path is relative. Must end * in '/'. * @param pszBuf Where to write the path. Must be at least * sizeof(@a pszPrefix) characters long * @param cchBuf The size of the buffer pointed to by @a pszBuf. * @param pszFormat The name format, either absolute or relative to the * prefix specified by @a pszPrefix. * @param va The format args. */ static ssize_t rtLinuxConstructPathV(char *pszBuf, size_t cchBuf, const char *pszPrefix, const char *pszFormat, va_list va) { size_t cchPrefix = strlen(pszPrefix); AssertReturnStmt(pszPrefix[cchPrefix - 1] == '/', errno = ERANGE, -1); AssertReturnStmt(cchBuf > cchPrefix + 1, errno = ERANGE, -1); /** @todo While RTStrPrintfV prevents overflows, it doesn't make it easy to * check for truncations. RTPath should provide some formatters and * joiners which can take over this rather common task that is * performed here. */ size_t cch = RTStrPrintfV(pszBuf, cchBuf, pszFormat, va); if (*pszBuf != '/') { AssertReturnStmt(cchBuf >= cch + cchPrefix + 1, errno = ERANGE, -1); memmove(pszBuf + cchPrefix, pszBuf, cch + 1); memcpy(pszBuf, pszPrefix, cchPrefix); cch += cchPrefix; } return cch; }
/** * Worker for RTAssertMsg2V and RTAssertMsg2AddV * * @param fInitial True if it's RTAssertMsg2V, otherwise false. * @param pszFormat The message format string. * @param va The format arguments. */ static void rtAssertMsg2Worker(bool fInitial, const char *pszFormat, va_list va) { va_list vaCopy; size_t cch; /* * The global first. */ if (fInitial) { va_copy(vaCopy, va); cch = RTStrPrintfV(g_szRTAssertMsg2, sizeof(g_szRTAssertMsg2), pszFormat, vaCopy); ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch); va_end(vaCopy); } else { cch = ASMAtomicReadU32(&g_cchRTAssertMsg2); if (cch < sizeof(g_szRTAssertMsg2) - 4) { va_copy(vaCopy, va); cch += RTStrPrintfV(&g_szRTAssertMsg2[cch], sizeof(g_szRTAssertMsg2) - cch, pszFormat, vaCopy); ASMAtomicWriteU32(&g_cchRTAssertMsg2, (uint32_t)cch); va_end(vaCopy); } } /* * If not quiet, make some noise. */ if (!RTAssertAreQuiet()) { RTERRVARS SavedErrVars; RTErrVarsSave(&SavedErrVars); #ifdef IN_RING0 # ifdef IN_GUEST_R0 va_copy(vaCopy, va); RTLogBackdoorPrintfV(pszFormat, vaCopy); va_end(vaCopy); # endif /** @todo fully integrate this with the logger... play safe a bit for now. */ rtR0AssertNativeMsg2V(fInitial, pszFormat, va); #else /* !IN_RING0 */ # if !defined(IN_RING3) && !defined(LOG_NO_COM) # if 0 /* Enable this iff you have a COM port and really want this debug info. */ va_copy(vaCopy, va); RTLogComPrintfV(pszFormat, vaCopy); va_end(vaCopy); # endif # endif PRTLOGGER pLog = RTLogRelGetDefaultInstance(); if (pLog) { va_copy(vaCopy, va); RTLogRelPrintfV(pszFormat, vaCopy); va_end(vaCopy); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); # endif } pLog = RTLogDefaultInstance(); if (pLog) { va_copy(vaCopy, va); RTLogPrintfV(pszFormat, vaCopy); va_end(vaCopy); # ifndef IN_RC /* flushing is done automatically in RC */ RTLogFlush(pLog); #endif } # ifdef IN_RING3 /* print to stderr, helps user and gdb debugging. */ char szMsg[sizeof(g_szRTAssertMsg2)]; va_copy(vaCopy, va); RTStrPrintfV(szMsg, sizeof(szMsg), pszFormat, vaCopy); va_end(vaCopy); fprintf(stderr, "%s", szMsg); fflush(stderr); # endif #endif /* !IN_RING0 */ RTErrVarsRestore(&SavedErrVars); } }
/** * Special entrypoint used by the hardening code when something goes south. * * Display an error dialog to the user. * * @param pszWhere Indicates where the error occured. * @param enmWhat Indicates what init operation was going on at the time. * @param rc The VBox status code corresponding to the error. * @param pszMsgFmt The message format string. * @param va Format arguments. */ extern "C" DECLEXPORT(void) TrustedError(const char *pszWhere, SUPINITOP enmWhat, int rc, const char *pszMsgFmt, va_list va) { # ifdef VBOX_WS_MAC /* Hide setuid root from AppKit: */ HideSetUidRootFromAppKit(); # endif /* VBOX_WS_MAC */ char szMsgBuf[_16K]; /* * We have to create QApplication anyway just to show the only one error-message. * This is a bit hackish as we don't have the argument vector handy. */ int argc = 0; char *argv[2] = { NULL, NULL }; QApplication a(argc, &argv[0]); /* * The details starts off a properly formatted rc and where/what, we use * the szMsgBuf for this, thus this have to come before the actual message * formatting. */ RTStrPrintf(szMsgBuf, sizeof(szMsgBuf), "<!--EOM-->" "where: %s\n" "what: %d\n" "%Rra\n", pszWhere, enmWhat, rc); QString strDetails = szMsgBuf; /* * Format the error message. Take whatever comes after a double new line as * something better off in the details section. */ RTStrPrintfV(szMsgBuf, sizeof(szMsgBuf), pszMsgFmt, va); char *pszDetails = strstr(szMsgBuf, "\n\n"); if (pszDetails) { while (RT_C_IS_SPACE(*pszDetails)) *pszDetails++ = '\0'; if (*pszDetails) { strDetails += "\n"; strDetails += pszDetails; } RTStrStripR(szMsgBuf); } QString strText = QApplication::tr("<html><b>%1 (rc=%2)</b><br/><br/>").arg(szMsgBuf).arg(rc); strText.replace(QString("\n"), QString("<br>")); /* * Append possibly helpful hints to the error message. */ switch (enmWhat) { case kSupInitOp_Driver: # ifdef RT_OS_LINUX strText += g_QStrHintLinuxNoDriver; # else /* RT_OS_LINUX */ strText += g_QStrHintOtherNoDriver; # endif /* !RT_OS_LINUX */ break; # ifdef RT_OS_LINUX case kSupInitOp_IPRT: case kSupInitOp_Misc: if (rc == VERR_NO_MEMORY) strText += g_QStrHintLinuxNoMemory; else # endif /* RT_OS_LINUX */ if (rc == VERR_VM_DRIVER_VERSION_MISMATCH) # ifdef RT_OS_LINUX strText += g_QStrHintLinuxWrongDriverVersion; # else /* RT_OS_LINUX */ strText += g_QStrHintOtherWrongDriverVersion; # endif /* !RT_OS_LINUX */ else strText += g_QStrHintReinstall; break; case kSupInitOp_Integrity: case kSupInitOp_RootCheck: strText += g_QStrHintReinstall; break; default: /* no hints here */ break; }