/** * Write a formatted string to the console, lookup the last port error message and port error number, then store it. * * Update the number of failed tests * * * @param[in] portLibrary The port library * @param[in] fileName File requesting message output * @param[in] lineNumber Line number in the file of request * @param[in] testName Name of the test requesting output * @param[in] foramt Format of string to be output * @param[in] ... argument list for format string */ void outputErrorMessage(struct OMRPortLibrary *portLibrary, const char *fileName, int32_t lineNumber, const char *testName, const char *format, ...) { char *buf, *portErrorBuf = NULL; uintptr_t sizeBuf; size_t sizePortErrorBuf; va_list args; char *lastErrorMessage = NULL; int32_t lastErrorNumber = 0; OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); lastErrorMessage = (char *)omrerror_last_error_message(); lastErrorNumber = omrerror_last_error_number(); /* Capture the error message now * Get the size needed to hold the last error message (don't use str_printf to avoid polluting error message */ sizePortErrorBuf = strlen(lastErrorMessage) + 1 /* for the null terminator */; portErrorBuf = (char *)omrmem_allocate_memory(sizePortErrorBuf, OMRMEM_CATEGORY_PORT_LIBRARY); if (NULL != portErrorBuf) { strncpy(portErrorBuf, lastErrorMessage, sizePortErrorBuf); } else { portTestEnv->log(LEVEL_ERROR, "\n\n******* omrmem_allocate_memory failed to allocate %i bytes, exiting.\n\n", sizePortErrorBuf); exit(EXIT_OUT_OF_MEMORY); } va_start(args, format); /* get the size needed to hold the error message that was passed in */ sizeBuf = omrstr_vprintf(NULL, 0, format, args); buf = (char *)omrmem_allocate_memory(sizeBuf, OMRMEM_CATEGORY_PORT_LIBRARY); if (NULL != buf) { omrstr_vprintf(buf, sizeBuf, format, args); } else { portTestEnv->log(LEVEL_ERROR, "\n\n******* omrmem_allocate_memory failed to allocate %i bytes, exiting.\n\n", sizeBuf); exit(EXIT_OUT_OF_MEMORY); } va_end(args); portTestEnv->log(LEVEL_ERROR, "%s line %4zi: %s ", fileName, lineNumber, testName); portTestEnv->log(LEVEL_ERROR, "%s\n", buf); portTestEnv->log(LEVEL_ERROR, "\t\tLastErrorNumber: %i\n", lastErrorNumber); portTestEnv->log(LEVEL_ERROR, "\t\tLastErrorMessage: %s\n\n", portErrorBuf); logTestFailure(OMRPORTLIB, fileName, lineNumber, testName, lastErrorNumber, portErrorBuf, buf); omrmem_free_memory(portErrorBuf); omrmem_free_memory(buf); numberFailedTestsInComponent++; }
bool MM_VerboseBuffer::vprintf(MM_EnvironmentBase *env, const char *format, va_list args) { OMRPORT_ACCESS_FROM_OMRPORT(env->getPortLibrary()); bool result = true; uintptr_t spaceFree = freeSpace(); va_list argsCopy; Assert_VGC_true('\0' == _bufferAlloc[0]); COPY_VA_LIST(argsCopy, args); uintptr_t spaceUsed = omrstr_vprintf(_bufferAlloc, spaceFree, format, argsCopy); /* account for the '\0' which isn't included in spaceUsed */ if ((spaceUsed + 1) < spaceFree) { /* the string fit in the buffer */ _bufferAlloc += spaceUsed; Assert_VGC_true('\0' == _bufferAlloc[0]); } else { /* undo anything that might have been written by the failed call to omrstr_vprintf */ _bufferAlloc[0] = '\0'; /* grow the buffer and try again */ COPY_VA_LIST(argsCopy, args); uintptr_t spaceNeeded = omrstr_vprintf(NULL, 0, format, argsCopy); if (ensureCapacity(env, spaceNeeded)) { COPY_VA_LIST(argsCopy, args); spaceUsed = omrstr_vprintf(_bufferAlloc, freeSpace(), format, argsCopy); Assert_VGC_true(spaceUsed < freeSpace()); _bufferAlloc += spaceUsed; Assert_VGC_true('\0' == _bufferAlloc[0]); } else { /* failed to expand buffer */ result = false; } } return result; }