void OMR_MethodDictionary::formatEntryProperties(const OMR_MethodDictionaryEntry *entry, char **str) const { if (_numProperties == 0) { *str = NULL; } else { OMRPORT_ACCESS_FROM_OMRVM(_vm); size_t buflen = _numProperties; /* space between each property + nul-terminator, might include some extra if we have nulls */ for (size_t i = 0; i < _numProperties; ++i) { if (NULL != entry->propertyValues[i]) { buflen += strlen(entry->propertyValues[i]); } } char *buf = (char *)omrmem_allocate_memory(buflen, OMRMEM_CATEGORY_OMRTI); uintptr_t bufUsed = 0; if (NULL != buf) { bufUsed += omrstr_printf(buf, (uintptr_t)buflen, "%s", entry->propertyValues[0]); for (size_t i = 1; i < _numProperties; ++i) { if (NULL != entry->propertyValues[i]) { bufUsed += omrstr_printf(buf + bufUsed, (uintptr_t)buflen - bufUsed, " %s", entry->propertyValues[i]); } } } *str = buf; } }
bool MM_VerboseWriter::initialize(MM_EnvironmentBase* env) { OMRPORT_ACCESS_FROM_OMRPORT(env->getPortLibrary()); MM_GCExtensionsBase* ext = env->getExtensions(); /* Initialize _header */ const char* version = omrgc_get_version(env->getOmrVM()); /* The length is -2 for the "%s" in VERBOSEGC_HEADER and +1 for '\0' */ uintptr_t headerLength = strlen(version) + strlen(VERBOSEGC_HEADER) - 1; _header = (char*)ext->getForge()->allocate(sizeof(char) * headerLength, OMR::GC::AllocationCategory::DIAGNOSTIC, OMR_GET_CALLSITE()); if (NULL == _header) { return false; } omrstr_printf(_header, headerLength, VERBOSEGC_HEADER, version); /* Initialize _footer */ uintptr_t footerLength = strlen(VERBOSEGC_FOOTER) + 1; _footer = (char*)ext->getForge()->allocate(sizeof(char) * footerLength, OMR::GC::AllocationCategory::DIAGNOSTIC, OMR_GET_CALLSITE()); if (NULL == _footer) { ext->getForge()->free(_header); return false; } omrstr_printf(_footer, footerLength, VERBOSEGC_FOOTER); return true; }
/** * Removes a directory by recursively removing sub-directory and files. * * @param[in] portLibrary The port library * @param[in] directory to clean up * * @return void */ void deleteControlDirectory(struct OMRPortLibrary *portLibrary, char *baseDir) { OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); struct J9FileStat buf; omrfile_stat(baseDir, (uint32_t)0, &buf); if (buf.isDir != 1) { omrfile_unlink(baseDir); } else { char mybaseFilePath[EsMaxPath]; char resultBuffer[EsMaxPath]; uintptr_t rc, handle; omrstr_printf(mybaseFilePath, EsMaxPath, "%s", baseDir); rc = handle = omrfile_findfirst(mybaseFilePath, resultBuffer); while ((uintptr_t)-1 != rc) { char nextEntry[EsMaxPath]; /* skip current and parent dir */ if (resultBuffer[0] == '.') { rc = omrfile_findnext(handle, resultBuffer); continue; } omrstr_printf(nextEntry, EsMaxPath, "%s/%s", mybaseFilePath, resultBuffer); deleteControlDirectory(OMRPORTLIB, nextEntry); rc = omrfile_findnext(handle, resultBuffer); } if (handle != (uintptr_t)-1) { omrfile_findclose(handle); } omrfile_unlinkdir(mybaseFilePath); } }
/** * Initialize a new lock object. * A lock must be initialized before it may be used. * * @param env * @param options * @param name Lock name * @return TRUE on success * @note Creates a store barrier. */ bool MM_LightweightNonReentrantLock::initialize(MM_EnvironmentBase *env, ModronLnrlOptions *options, const char * name) { OMRPORT_ACCESS_FROM_OMRPORT(env->getPortLibrary()); /* initialize variables in case constructor was not called */ _initialized = false; _tracing = NULL; _extensions = env->getExtensions(); if (NULL != _extensions) { J9Pool* tracingPool = _extensions->_lightweightNonReentrantLockPool; if (NULL != tracingPool) { omrthread_monitor_enter(_extensions->_lightweightNonReentrantLockPoolMutex); _tracing = (J9ThreadMonitorTracing *)pool_newElement(tracingPool); omrthread_monitor_exit(_extensions->_lightweightNonReentrantLockPoolMutex); if (NULL == _tracing) { goto error_no_memory; } _tracing->monitor_name = NULL; if (NULL != name) { uintptr_t length = omrstr_printf(NULL, 0, "[%p] %s", this, name) + 1; if (length > MAX_LWNR_LOCK_NAME_SIZE) { goto error_no_memory; } _tracing->monitor_name = _nameBuf; if (NULL == _tracing->monitor_name) { goto error_no_memory; } omrstr_printf(_tracing->monitor_name, length, "[%p] %s", this, name); } } } #if defined(OMR_ENV_DATA64) if(0 != (((uintptr_t)this) % sizeof(uintptr_t))) { omrtty_printf("GC FATAL: LWNRL misaligned.\n"); abort(); } #endif #if defined(J9MODRON_USE_CUSTOM_SPINLOCKS) _initialized = omrgc_spinlock_init(&_spinlock) ? false : true; _spinlock.spinCount1 = options->spinCount1; _spinlock.spinCount2 = options->spinCount2; _spinlock.spinCount3 = options->spinCount3; #else /* J9MODRON_USE_CUSTOM_SPINLOCKS */ _initialized = MUTEX_INIT(_mutex) ? true : false; #endif /* J9MODRON_USE_CUSTOM_SPINLOCKS */ return _initialized; error_no_memory: return false; }
uintptr_t MM_VerboseHandlerOutput::getTagTemplate(char *buf, uintptr_t bufsize, uintptr_t id, const char *type, uintptr_t contextId, uint64_t timeus, uint64_t wallTimeMs) { OMRPORT_ACCESS_FROM_OMRVM(_omrVM); uintptr_t bufPos = 0; bufPos += omrstr_printf(buf, bufsize, "id=\"%zu\" type=\"%s\" timems=\"%llu.%03.3llu\" contextid=\"%zu\" timestamp=\"", id, type, timeus / 1000, timeus % 1000, contextId); bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_PRE_MS, wallTimeMs); bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "%03llu", wallTimeMs % 1000); bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_POST_MS, wallTimeMs); bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "\""); return bufPos; }
uintptr_t MM_VerboseHandlerOutput::getTagTemplate(char *buf, uintptr_t bufsize, uint64_t wallTimeMs) { OMRPORT_ACCESS_FROM_OMRVM(_omrVM); uintptr_t bufPos = 0; bufPos += omrstr_printf(buf, bufsize, "timestamp=\""); bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_PRE_MS, wallTimeMs); bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "%03llu", wallTimeMs % 1000); bufPos += omrstr_ftime(buf + bufPos, bufsize - bufPos, VERBOSEGC_DATE_FORMAT_POST_MS, wallTimeMs); bufPos += omrstr_printf(buf + bufPos, bufsize - bufPos, "\""); return bufPos; }
ObjectEntry * GCConfigTest::createObject(const char *namePrefix, OMRGCObjectType objType, int32_t depth, int32_t nthInRow, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); ObjectEntry *objEntry = NULL; char *objName = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM); if (NULL == objName) { omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefix, depth, nthInRow); objEntry = find(objName); if (NULL != objEntry) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("Found object %s in object table.\n", objEntry->name); #endif omrmem_free_memory(objName); } else { objEntry = allocateHelper(objName, size); if (NULL != objEntry) { /* Keep count of the new allocated non-garbage object size for garbage insertion. If the object exists in objectTable, its size is ignored. */ if ((ROOT == objType) || (NORMAL == objType)) { gp.accumulatedSize += env->getExtensions()->objectModel.getSizeInBytesWithHeader(objEntry->objPtr); } } else { omrmem_free_memory(objName); } } done: return objEntry; }
bool MM_VerboseHandlerOutput::getThreadName(char *buf, uintptr_t bufLen, OMR_VMThread *vmThread) { OMRPORT_ACCESS_FROM_OMRVM(_omrVM); omrstr_printf(buf, bufLen, "OMR_VMThread [%p]",vmThread); return true; }
uintptr_t escapeXMLString(OMRPortLibrary *portLibrary, char *outBuf, uintptr_t outBufLen, const char *string, uintptr_t stringLen) { uintptr_t stringPos = 0; uintptr_t outBufPos = 0; OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); if (0 == outBufLen) { return 0; } /* null terminate in case we can't fit anything in the buffer */ outBuf[0] = '\0'; for (stringPos = 0; stringPos < stringLen; ++stringPos) { uintptr_t tmpBufLen = 0; char tmpBuf[8]; switch (string[stringPos]) { case '<': strcpy(tmpBuf, "<"); break; case '>': strcpy(tmpBuf, ">"); break; case '&': strcpy(tmpBuf, "&"); break; case '\'': strcpy(tmpBuf, "'"); break; case '\"': strcpy(tmpBuf, """); break; default: if (((uint8_t)(string[stringPos])) < 0x20) { /* use XML escape sequence for characters below 0x20 */ omrstr_printf(tmpBuf, sizeof(tmpBuf), "&#x%X;", (uint32_t)string[stringPos]); } else { tmpBuf[0] = string[stringPos]; tmpBuf[1] = '\0'; } break; } /* finish if the output buffer is full */ tmpBufLen = strlen(tmpBuf); if (outBufPos + tmpBufLen > outBufLen - 1) { break; } strcpy(outBuf + outBufPos, tmpBuf); outBufPos += tmpBufLen; } return stringPos; }
/* * Test scenario for CorruptedAgent: * - create an empty agent file * - call omr_agent_create() and OMR_Agent::createAgent by providing the empty agent file * - expect openLibrary() to fail */ TEST_F(RASAgentNegativeTest, CorruptedAgent) { intptr_t fileDescriptor; char fileName[256]; char agentName[256]; char hostname[128]; OMRPORT_ACCESS_FROM_OMRVM(&testVM.omrVM); ASSERT_EQ(0, gethostname(hostname, sizeof(hostname))); /* generate machine specific file name to prevent conflict between multiple tests running on shared drive */ omrstr_printf(agentName, sizeof(agentName), "corruptedAgent_%s", hostname); /* create fileName with platform-dependent shared library prefix & suffix. * for Windows, fileName = corruptedAgent_<hostname>.dll * for Unix, fileName = libcorruptedAgent_<hostname>.so * for OSX, fileName = libcorruptedAgent_<hostname>.dylib */ #if defined(WIN32) || defined(WIN64) omrstr_printf(fileName, sizeof(fileName), "%s.dll", agentName); #elif defined(OSX) omrstr_printf(fileName, sizeof(fileName), "lib%s.dylib", agentName); #else /* defined(OSX) */ omrstr_printf(fileName, sizeof(fileName), "lib%s.so", agentName); #endif /* defined(WIN32) || defined(WIN64) */ /* create the empty agent file with permission 751*/ fileDescriptor = omrfile_open(fileName, EsOpenCreate | EsOpenWrite, 0751); ASSERT_NE(-1, fileDescriptor) << "omrfile_open \"" << fileName << "\" failed"; omrfile_close(fileDescriptor); /* call omr_agent_create() by providing the empty agent file */ struct OMR_Agent *agentC = omr_agent_create(&testVM.omrVM, agentName); ASSERT_FALSE(NULL == agentC) << "testAgent: createAgent() " << agentName << " failed"; OMRTEST_ASSERT_ERROR(OMR_ERROR_ILLEGAL_ARGUMENT, omr_agent_openLibrary(agentC)); /* call OMR_Agent::createAgent() by providing the empty agent file */ OMR_Agent *agentCPP = OMR_Agent::createAgent(&testVM.omrVM, agentName); ASSERT_FALSE(NULL == agentCPP) << "testAgent: createAgent() failed"; OMRTEST_ASSERT_ERROR(OMR_ERROR_ILLEGAL_ARGUMENT, agentCPP->openLibrary()); omrfile_unlink(fileName); }
int32_t GCConfigTest::insertGarbage() { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 0; char fullNamePrefix[MAX_NAME_LENGTH]; omrstr_printf(fullNamePrefix, sizeof(fullNamePrefix), "%s_%d", gp.namePrefix, gp.garbageSeq++); int32_t breadth = 2; uintptr_t totalSize = (uintptr_t)(gp.accumulatedSize * gp.percentage) / 100; uintptr_t objSize = 0; if (0 == strcmp(gp.structure, "node")) { objSize = totalSize; } else if (0 == strcmp(gp.structure, "tree")) { objSize = 64; } #if defined(OMRGCTEST_DEBUG) omrtty_printf("Inserting garbage %s of %dB (%f%% of previous object/tree size %dB) ...\n", fullNamePrefix, totalSize, gp.percentage, gp.accumulatedSize); #endif omrobjectptr_t rootObj = NULL; rt = createFixedSizeTree(&rootObj, fullNamePrefix, GARBAGE_ROOT, totalSize, objSize, breadth); OMRGCTEST_CHECK_RT(rt); /* remove garbage root object from the root set */ if (NULL != rootObj) { char rootObjName[MAX_NAME_LENGTH]; omrstr_printf(rootObjName, MAX_NAME_LENGTH, "%s_%d_%d", fullNamePrefix, 0, 0); rt = removeObjectFromRootTable(rootObjName); OMRGCTEST_CHECK_RT(rt); } /* reset accumulatedSize */ gp.accumulatedSize = 0; done: return rt; }
int32_t GCConfigTest::createObject(omrobjectptr_t *obj, char **objName, const char *namePrefix, OMRGCObjectType objType, int32_t depth, int32_t nthInRow, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; ObjectEntry *objEntry = NULL; *objName = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM); if (NULL == *objName) { rt = 1; omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } omrstr_printf(*objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefix, depth, nthInRow); if (0 == objectTable.find(&objEntry, *objName)) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("Find object %s in hash table.\n", *objName); #endif *obj = objEntry->objPtr; } else { rt = allocateHelper(obj, *objName, size); OMRGCTEST_CHECK_RT(rt); /* keep object in table */ rt = objectTable.add(*objName, *obj, 0); OMRGCTEST_CHECK_RT(rt) /* Keep count of the new allocated non-garbage object size for garbage insertion. If the object exists in objectTable, its size is ignored. */ if ((ROOT == objType) || (NORMAL == objType)) { gp.accumulatedSize += env->getExtensions()->objectModel.getSizeInBytesWithHeader(*obj); } } done: return rt; }
int32_t GCConfigTest::processObjNode(pugi::xml_node node, const char *namePrefixStr, OMRGCObjectType objType, AttributeElem *numOfFieldsElem, AttributeElem *breadthElem, int32_t depth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; OMR_VM *omrVMPtr = exampleVM->_omrVM; int32_t numOfParents = 0; /* Create objects and store them in the root table or the slot object based on objType. */ if ((ROOT == objType) || (GARBAGE_ROOT == objType)) { for (int32_t i = 0; i < breadthElem->value; i++) { omrobjectptr_t obj; char *objName = NULL; uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); rt = createObject(&obj, &objName, namePrefixStr, objType, 0, i, sizeCalculated); OMRGCTEST_CHECK_RT(rt); numOfFieldsElem = numOfFieldsElem->linkNext; /* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/ RootEntry rEntry; rEntry.name = objName; rEntry.rootPtr = obj; if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) { rt = 1; omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__); goto done; } /* insert garbage per node */ if ((ROOT == objType) && (0 == strcmp(gp.frequency, "perObject"))) { rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } } } else if ((NORMAL == objType) || (GARBAGE_TOP == objType) || (GARBAGE_CHILD == objType)) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parent = parentEntry->objPtr; GC_ObjectIterator objectIterator(omrVMPtr, parent); objectIterator.restore(parentEntry->numOfRef); for (int32_t i = 0; i < breadthElem->value; i++) { omrobjectptr_t obj; char *objName = NULL; uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); rt = createObject(&obj, &objName, namePrefixStr, objType, 0, i, sizeCalculated); OMRGCTEST_CHECK_RT(rt); numOfFieldsElem = numOfFieldsElem->linkNext; GC_SlotObject *slotObject = NULL; if (NULL != (slotObject = objectIterator.nextSlot())) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd to slot of parent(%llu) %d\n", parent, parentEntry->numOfRef + i); #endif /* Add object to parent's slot. If it's the top of the garbage tree, temporarily keep it in the slot until * the rest of the tree is allocated. */ slotObject->writeReferenceToSlot(obj); } else { rt = 1; omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName); goto done; } /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } } parentEntry->numOfRef += breadthElem->value; } else { rt = 1; goto done; } /* Create the rest of the tree, if any, defined with depth. First, we set the child object with correct objType. */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } numOfParents = breadthElem->value; breadthElem = breadthElem->linkNext; for (int32_t i = 1; i < depth; i++) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (i - 1), j); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parent = parentEntry->objPtr; GC_ObjectIterator objectIterator(omrVMPtr, parent); objectIterator.restore(parentEntry->numOfRef); for (int32_t k = 0; k < breadthElem->value; k++) { omrobjectptr_t obj; char *objName = NULL; uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); rt = createObject(&obj, &objName, namePrefixStr, objType, i, nthInRow, sizeCalculated); OMRGCTEST_CHECK_RT(rt); numOfFieldsElem = numOfFieldsElem->linkNext; nthInRow += 1; GC_SlotObject *slotObject = NULL; if (NULL != (slotObject = objectIterator.nextSlot())) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd to parent(%llu) slot %d.\n", parent, parentEntry->numOfRef + k); #endif slotObject->writeReferenceToSlot(obj); } else { rt = 1; omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName); goto done; } /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } } parentEntry->numOfRef += breadthElem->value; } numOfParents = nthInRow; breadthElem = breadthElem->linkNext; } done: return rt; }
omr_error_t initialiseComponentData(UtComponentData **componentDataPtr, UtModuleInfo *moduleInfo, const char *componentName) { OMRPORT_ACCESS_FROM_OMRPORT(OMR_TRACEGLOBAL(portLibrary)); UtComponentData *componentData = (UtComponentData *)omrmem_allocate_memory(sizeof(UtComponentData), OMRMEM_CATEGORY_TRACE); UT_DBGOUT(2, ("<UT> initialiseComponentData: %s\n", componentName)); if (componentData == NULL) { UT_DBGOUT(1, ("<UT> Unable to allocate componentData for %s\n", componentName)); return OMR_ERROR_OUT_OF_NATIVE_MEMORY; } initHeader(&componentData->header, UT_TRACE_COMPONENT_DATA, sizeof(UtComponentData)); componentData->componentName = (char *)omrmem_allocate_memory(strlen(componentName) + 1, OMRMEM_CATEGORY_TRACE); if (componentData->componentName == NULL) { UT_DBGOUT(1, ("<UT> Unable to allocate componentData's name field for %s\n", componentName)); return OMR_ERROR_OUT_OF_NATIVE_MEMORY; } strcpy(componentData->componentName, componentName); /* Setup the fully qualified name here as when we come to print out trace counters the modules may have been * freed already. */ if (moduleInfo->traceVersionInfo->traceVersion >= 7 && moduleInfo->containerModule != NULL) { char qualifiedName[MAX_QUALIFIED_NAME_LENGTH]; omrstr_printf(qualifiedName, MAX_QUALIFIED_NAME_LENGTH, "%s(%s)", moduleInfo->name, moduleInfo->containerModule->name); componentData->qualifiedComponentName = (char *)omrmem_allocate_memory(strlen(qualifiedName) + 1, OMRMEM_CATEGORY_TRACE); if (componentData->qualifiedComponentName == NULL) { UT_DBGOUT(1, ("<UT> Unable to allocate componentData's name field for %s\n", componentName)); return OMR_ERROR_OUT_OF_NATIVE_MEMORY; } strcpy(componentData->qualifiedComponentName, qualifiedName); } else { componentData->qualifiedComponentName = componentData->componentName; } if (moduleInfo->formatStringsFileName != NULL) { componentData->formatStringsFileName = (char *)omrmem_allocate_memory(strlen(moduleInfo->formatStringsFileName) + 1, OMRMEM_CATEGORY_TRACE); if (componentData->formatStringsFileName == NULL) { UT_DBGOUT(1, ("<UT> Unable to allocate componentData's format strings file name field for %s\n", componentName)); return OMR_ERROR_OUT_OF_NATIVE_MEMORY; } strcpy(componentData->formatStringsFileName, moduleInfo->formatStringsFileName); } else { componentData->formatStringsFileName = NULL; } componentData->moduleInfo = moduleInfo; componentData->tracepointCount = moduleInfo->count; componentData->numFormats = 0; componentData->tracepointFormattingStrings = NULL; componentData->tracepointcounters = NULL; componentData->alreadyfailedtoloaddetails = 0; componentData->next = NULL; componentData->prev = NULL; *componentDataPtr = componentData; UT_DBGOUT(2, ("<UT> initialiseComponentData complete: %s\n", componentName)); return OMR_ERROR_NONE; }
int32_t GCConfigTest::createFixedSizeTree(ObjectEntry **rootEntryIndirectPtr, const char *namePrefixStr, OMRGCObjectType objType, uintptr_t totalSize, uintptr_t objSize, int32_t breadth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); *rootEntryIndirectPtr = NULL; int32_t rt = 0; uintptr_t bytesLeft = totalSize; if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { return rt; } } bytesLeft -= objSize; rt = 1; int32_t depth = 1; int32_t numOfParents = 1; /* allocate the root object and add it to the object table */ *rootEntryIndirectPtr = createObject(namePrefixStr, objType, 0, 0, objSize); if (NULL == *rootEntryIndirectPtr) { goto done; } /* add it to the root table */ RootEntry rootEntry; rootEntry.name = (*rootEntryIndirectPtr)->name; rootEntry.rootPtr = (*rootEntryIndirectPtr)->objPtr; if (NULL == hashTableAdd(exampleVM->rootTable, &rootEntry)) { omrtty_printf("%s:%d Failed to add new root entry %s to root table!\n", __FILE__, __LINE__, rootEntry.name); goto done; } /* create the rest of the tree */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } while (bytesLeft > 0) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (depth - 1), j); ObjectEntry *parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } for (int32_t k = 0; k < breadth; k++) { if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { rt = 0; goto done; } } ObjectEntry *childEntry = createObject(namePrefixStr, objType, depth, nthInRow, objSize); if (NULL == childEntry) { goto done; } parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } if (0 != attachChildEntry(parentEntry, childEntry)) { goto done; } bytesLeft -= objSize; nthInRow += 1; } parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } } numOfParents = nthInRow; depth += 1; } *rootEntryIndirectPtr = find(rootEntry.name); if (NULL == *rootEntryIndirectPtr) { omrtty_printf("%s:%d Could not find root of fixed-size tree %s in object table.\n", __FILE__, __LINE__, rootEntry.name); goto done; } rt = 0; done: return rt; }
intptr_t j9process_create(OMRPortLibrary *portLibrary, const char *command[], uintptr_t commandLength, const char *dir, uint32_t options, OMRProcessHandle *processHandle) { OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); intptr_t rc = 0; OMRProcessHandleStruct *processHandleStruct = NULL; #if defined(WIN32) STARTUPINFOW sinfo; PROCESS_INFORMATION pinfo; SECURITY_ATTRIBUTES sAttrib; wchar_t *unicodeDir = NULL; wchar_t *unicodeCmdline = NULL; wchar_t *unicodeEnv = NULL; OMRProcessWin32Pipes pipes; DWORD dwMode = PIPE_NOWAIT; /* it's only used if OMRPORT_PROCESS_NONBLOCKING_IO is set */ if (0 == commandLength) { return OMRPROCESS_ERROR; } processHandleStruct = (OMRProcessHandleStruct *)omrmem_allocate_memory(sizeof(OMRProcessHandleStruct), OMRMEM_CATEGORY_PORT_LIBRARY); ZeroMemory(&sinfo, sizeof(sinfo)); ZeroMemory(&pinfo, sizeof(pinfo)); ZeroMemory(&sAttrib, sizeof(sAttrib)); sinfo.cb = sizeof(sinfo); sinfo.dwFlags = STARTF_USESTDHANDLES; /* Allow handle inheritance */ sAttrib.bInheritHandle = 1; sAttrib.nLength = sizeof(sAttrib); ZeroMemory(&pipes, sizeof(OMRProcessWin32Pipes)); // Create input pipe if (0 == CreatePipe(&(pipes.inR), &(pipes.inW), &sAttrib, 512)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } else { if (0 == DuplicateHandle(GetCurrentProcess(), pipes.inW, GetCurrentProcess(), &(pipes.inDup), 0, FALSE, DUPLICATE_SAME_ACCESS)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } if (0 == CloseHandle(pipes.inW)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } pipes.inW = NULL; } sinfo.hStdInput = pipes.inR; processHandleStruct->inHandle = (intptr_t)pipes.inDup; if (OMRPROCESS_DEBUG == options) { processHandleStruct->outHandle = OMRPROCESS_INVALID_FD; if (sinfo.dwFlags == STARTF_USESTDHANDLES) { sinfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); } processHandleStruct->errHandle = OMRPROCESS_INVALID_FD; if (sinfo.dwFlags == STARTF_USESTDHANDLES) { sinfo.hStdError = GetStdHandle(STD_ERROR_HANDLE); } } else { // Create output pipe if (0 == CreatePipe(&(pipes.outR), &(pipes.outW), &sAttrib, 512)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } else { if (0 == DuplicateHandle(GetCurrentProcess(), pipes.outR, GetCurrentProcess(), &(pipes.outDup), 0, FALSE, DUPLICATE_SAME_ACCESS)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } if (0 == CloseHandle(pipes.outR)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } pipes.outR = NULL; } processHandleStruct->outHandle = (intptr_t)pipes.outDup; sinfo.hStdOutput = pipes.outW; // create error pipe if (0 == CreatePipe(&(pipes.errR), &(pipes.errW), &sAttrib, 512)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } else { if (0 == DuplicateHandle(GetCurrentProcess(), pipes.errR, GetCurrentProcess(), &(pipes.errDup), 0, FALSE, DUPLICATE_SAME_ACCESS)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } if (NULL != pipes.errR) { if (0 == CloseHandle(pipes.errR)) { closeAndDestroyPipes(&pipes); return OMRPROCESS_ERROR; } } pipes.errR = NULL; } processHandleStruct->errHandle = (intptr_t)pipes.errDup; sinfo.hStdError = pipes.errW; } if (0 == rc) { rc = getUnicodeCmdline(OMRPORTLIB, command, commandLength, &unicodeCmdline); if (0 == rc) { if (NULL != dir) { size_t length = strlen(dir); unicodeDir = (wchar_t *)omrmem_allocate_memory((length + 1) * 2, OMRMEM_CATEGORY_PORT_LIBRARY); if (NULL == unicodeDir) { rc = OMRPROCESS_ERROR; } else { convertFromUTF8(OMRPORTLIB, dir, unicodeDir, length + 1); } } if (0 == rc) { DWORD creationFlags = CREATE_UNICODE_ENVIRONMENT; if (0 == CreateProcessW( /* CreateProcessW returns 0 upon failure */ NULL, unicodeCmdline, NULL, NULL, TRUE, creationFlags, /* add DEBUG_ONLY_THIS_PROCESS for smoother debugging */ unicodeEnv, unicodeDir, &sinfo, &pinfo) /* Pointer to PROCESS_INFORMATION structure; */ ) { rc = OMRPROCESS_ERROR; } else { processHandleStruct->procHandle = (intptr_t) pinfo.hProcess; /* Close Handles passed to child if there is any */ CloseHandle(pipes.inR); if (OMRPROCESS_DEBUG != options) { CloseHandle(pipes.outW); CloseHandle(pipes.errW); } CloseHandle(pinfo.hThread); /* Implicitly created, a leak otherwise*/ } } } } if (NULL != unicodeCmdline) { omrmem_free_memory(unicodeCmdline); } if (NULL != unicodeDir) { omrmem_free_memory(unicodeDir); } if (NULL != unicodeEnv) { omrmem_free_memory(unicodeEnv); } if (0 != rc) { /* If an error occurred close all handles */ closeAndDestroyPipes(&pipes); } else { *processHandle = processHandleStruct; } return rc; #else /* defined(WIN32) */ const char *cmd = NULL; int grdpid; unsigned int i; int newFD[3][2]; int forkedChildProcess[2]; int pipeFailed = 0; int errorNumber = 0; char **newCommand; uintptr_t newCommandSize; if (0 == commandLength) { return OMRPROCESS_ERROR; } for (i = 0; i < 3; i += 1) { newFD[i][0] = OMRPROCESS_INVALID_FD; newFD[i][1] = OMRPROCESS_INVALID_FD; } /* Build the new io pipes (in/out/err) */ if (-1 == pipe(newFD[0])) { pipeFailed = 1; } if (OMRPROCESS_DEBUG != options) { if (-1 == pipe(newFD[1])) { pipeFailed = 1; } if (-1 == pipe(newFD[2])) { pipeFailed = 1; } } if (-1 == pipe(forkedChildProcess)) { /* pipe for synchronization */ forkedChildProcess[0] = OMRPROCESS_INVALID_FD; forkedChildProcess[1] = OMRPROCESS_INVALID_FD; pipeFailed = 1; } if (pipeFailed) { for (i = 0; i < 3; i++) { if (OMRPROCESS_INVALID_FD != newFD[i][0]) { if (-1 != rc) { rc = close(newFD[i][0]); } if (-1 != rc) { rc = close(newFD[i][1]); } } } if (OMRPROCESS_INVALID_FD != forkedChildProcess[0]) { if (-1 != rc) { rc = close(forkedChildProcess[0]); } if (-1 != rc) { rc = close(forkedChildProcess[1]); } } return OMRPROCESS_ERROR; } if (-1 != rc) { rc = setFdCloexec(forkedChildProcess[0]); } if (-1 != rc) { rc = setFdCloexec(forkedChildProcess[1]); } /* Create a NULL terminated array to contain the command for call to execv[p|e]() * We could do this in the child, but if mem_allocate_memory fails, it's easier to diagnose * failure in parent. Remember to free the memory */ newCommandSize = (commandLength + 1) * sizeof(uintptr_t); newCommand = (char **)omrmem_allocate_memory(newCommandSize, OMRMEM_CATEGORY_PORT_LIBRARY); if (NULL == newCommand) { return OMRPROCESS_ERROR; } memset(newCommand, 0, newCommandSize); for (i = 0 ; i < commandLength; i += 1) { #if defined(OSX) newCommand[i] = (char *)omrmem_allocate_memory(strlen(command[i]) + 1, OMRMEM_CATEGORY_PORT_LIBRARY); omrstr_printf(newCommand[i], strlen(command[i]) + 1, command[i]); #else /* defined(OSX) */ intptr_t translateStatus = translateModifiedUtf8ToPlatform(OMRPORTLIB, command[i], strlen(command[i]), &(newCommand[i])); if (0 != translateStatus) { unsigned int j = 0; /* most likely out of memory, free the strings we just converted. */ for (j = 0; j < i; j += 1) { if (NULL != newCommand[j]) { omrmem_free_memory(newCommand[j]); } } return translateStatus; } #endif /* defined(OSX) */ } cmd = newCommand[0]; newCommand[commandLength] = NULL; grdpid = fork(); if (grdpid == 0) { /* Child process */ char dummy = '\0'; /* Redirect pipes so grand-child inherits new pipes */ rc = dup2(newFD[0][0], 0); if (-1 != rc) { if (OMRPROCESS_DEBUG != options) { rc = dup2(newFD[1][1], 1); if (-1 != rc) { rc = dup2(newFD[2][1], 2); } } } /* tells the parent that that very process is running */ rc = write(forkedChildProcess[1], (void *) &dummy, 1); if ((-1 != rc) && dir) { rc = chdir(dir); } if (-1 != rc) { /* Try to perform the execv; on success, it does not return */ rc = execvp(cmd, newCommand); } /* If we get here, tell the parent that the execv failed! Send the error number. */ if (-1 != rc) { rc = write(forkedChildProcess[1], &errno, sizeof(errno)); } if (-1 != rc) { rc = close(forkedChildProcess[0]); } if (-1 != rc) { rc = close(forkedChildProcess[1]); } /* If the exec failed, we must exit or there will be two VM processes running. */ exit(rc); } else { /* In the parent process */ char dummy; for (i = 0; i < commandLength; i++) { if (NULL != newCommand[i]) { omrmem_free_memory(newCommand[i]); } } omrmem_free_memory(newCommand); if ((OMRPROCESS_INVALID_FD != newFD[0][0]) && (-1 != rc)) { rc = close(newFD[0][0]); } if ((OMRPROCESS_INVALID_FD != newFD[1][1]) && (-1 != rc)) { rc = close(newFD[1][1]); } if ((OMRPROCESS_INVALID_FD != newFD[2][1]) && (-1 != rc)) { rc = close(newFD[2][1]); } if (grdpid == -1) { /* the fork failed */ /* close the open pipes */ if (-1 != rc) { rc = close(forkedChildProcess[0]); } if (-1 != rc) { rc = close(forkedChildProcess[1]); } if ((OMRPROCESS_INVALID_FD != newFD[0][1]) && (-1 != rc)) { rc = close(newFD[0][1]); } if ((OMRPROCESS_INVALID_FD != newFD[1][0]) && (-1 != rc)) { rc = close(newFD[1][0]); } if ((OMRPROCESS_INVALID_FD != newFD[2][0]) && (-1 != rc)) { rc = close(newFD[2][0]); } return OMRPROCESS_ERROR; } /* Store the rw handles to the childs io */ processHandleStruct = (OMRProcessHandleStruct *)omrmem_allocate_memory(sizeof(OMRProcessHandleStruct), OMRMEM_CATEGORY_PORT_LIBRARY); processHandleStruct->inHandle = (intptr_t)newFD[0][1]; if (OMRPROCESS_DEBUG == options) { processHandleStruct->outHandle = OMRPROCESS_INVALID_FD; processHandleStruct->errHandle = OMRPROCESS_INVALID_FD; } else { processHandleStruct->outHandle = (intptr_t)newFD[1][0]; processHandleStruct->errHandle = (intptr_t)newFD[2][0]; } processHandleStruct->procHandle = (intptr_t)grdpid; processHandleStruct->pid = (int32_t)grdpid; /* let the forked child start. */ rc = close(forkedChildProcess[1]); if (-1 != rc) { rc = read(forkedChildProcess[0], &dummy, 1); } /* [PR CMVC 143339] * Instead of using timeout to determine if child process has been created successfully, * a single block read/write pipe call is used, if process creation failed, errorNumber * with sizeof(errno) will be returned, otherwise, read will fail due to pipe closure. */ if (-1 != rc) { rc = read(forkedChildProcess[0], &errorNumber, sizeof(errno)); } if (-1 != rc) { rc = close(forkedChildProcess[0]); } if (rc == sizeof(errno)) { return OMRPROCESS_ERROR; } *processHandle = processHandleStruct; return rc; } return OMRPROCESS_ERROR; #endif /* defined(WIN32) */ }
/* * Inform all registered listeners that the specified event has occurred. Details about the * event should be available through eventData. * * If the J9HOOK_TAG_ONCE bit is set in the taggedEventNum, then the event is disabled * before the listeners are informed. Any attempts to add listeners to a TAG_ONCE event * once it has been reported will fail. * * This function should not be called directly. It should be called through the hook interface * */ static void J9HookDispatch(struct J9HookInterface **hookInterface, uintptr_t taggedEventNum, void *eventData) { uintptr_t eventNum = taggedEventNum & J9HOOK_EVENT_NUM_MASK; J9CommonHookInterface *commonInterface = (J9CommonHookInterface *)hookInterface; J9HookRecord *record = HOOK_RECORD(commonInterface, eventNum); OMREventInfo4Dump *eventDump = J9HOOK_DUMPINFO(commonInterface, eventNum); uintptr_t samplingInterval = (taggedEventNum & J9HOOK_TAG_SAMPLING_MASK) >> 16; bool sampling = false; if (taggedEventNum & J9HOOK_TAG_ONCE) { uint8_t oldFlags; omrthread_monitor_enter(commonInterface->lock); oldFlags = HOOK_FLAGS(commonInterface, eventNum); /* clear the HOOKED and RESERVED flags and set the DISABLED flag */ HOOK_FLAGS(commonInterface, eventNum) = (oldFlags | J9HOOK_FLAG_DISABLED) & ~(J9HOOK_FLAG_RESERVED | J9HOOK_FLAG_HOOKED); omrthread_monitor_exit(commonInterface->lock); if (oldFlags & J9HOOK_FLAG_DISABLED) { /* already reported */ return; } } while (record) { J9HookFunction function; void *userData; uintptr_t id; /* ensure that the id is read before any other fields */ id = record->id; if (HOOK_IS_VALID_ID(id)) { VM_AtomicSupport::readBarrier(); function = record->function; userData = record->userData; /* now read the id again to make sure that nothing has changed */ VM_AtomicSupport::readBarrier(); if (record->id == id) { uint64_t startTime = 0; uintptr_t count = 0; if (NULL != eventDump) { count = VM_AtomicSupport::add((volatile uintptr_t *)&eventDump->count, 1); sampling = (1 >= samplingInterval) || ((100 >= samplingInterval) && (0 == (count % samplingInterval))); } else { sampling = false; } OMRPORT_ACCESS_FROM_OMRPORT(commonInterface->portLib); if (sampling) { startTime = omrtime_current_time_millis(); } function(hookInterface, eventNum, eventData, userData); if (sampling) { uint64_t timeDelta = omrtime_current_time_millis() - startTime; eventDump->lastHook.startTime = startTime; eventDump->lastHook.callsite = record->callsite; eventDump->lastHook.func_ptr = (void *)record->function; eventDump->lastHook.duration = timeDelta; if ((eventDump->longestHook.duration < timeDelta) || (0 == eventDump->longestHook.startTime)) { eventDump->longestHook.startTime = startTime; eventDump->longestHook.callsite = record->callsite; eventDump->longestHook.func_ptr = (void *)record->function; eventDump->longestHook.duration = timeDelta; } if (commonInterface->threshold4Trace <= timeDelta) { const char *callsite = "UNKNOWN"; char buffer[32]; if (NULL != record->callsite) { callsite = record->callsite; } else { /* if the callsite info can not be retrieved, use callback function pointer instead */ omrstr_printf(buffer, sizeof(buffer), "0x%p", record->function); callsite = buffer; } Trc_Hook_Dispatch_Exceed_Threshold_Event(callsite, timeDelta); } } } else { /* this record has been updated while we were reading it. Skip it. */ } } record = record->next; } }
/** * Verify port library error handling operations. * * Error codes are stored in per thread buffers so errors reported by one thread * do not effect those reported by a second. Errors stored via the helper * function @ref omrerror.c::omrerror_set_last_error_with_message_format "omrerror_set_last_error_with_message_format()" * are recorded in the per thread buffers without an error message. * Verify the @ref omrerror_last_error_message "omrerror_last_error_message()" returns * the correct message. */ TEST(PortErrorTest, error_test3) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrerror_test3"; const char *message; const char *formatMessage1 = "This is a test message with format specifiers %s %d"; const char *formatMessage2 = "This is also a test message with format specifiers %s %d"; const char *arg1 = "arg1"; int32_t arg2 = 1; char knownMessage[1024]; /* 1024 is large enough to hold format message */ int32_t errorCode; reportTestEntry(OMRPORTLIB, testName); /* Delete the ptBuffers */ omrport_tls_free(); /* In theory there is now nothing stored, if we really did free the buffers. * Guess it is time to find out */ message = omrerror_last_error_message(); if (0 != strlen(message)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned message of length %d expected %d\n", strlen(message), 0); } /* Set an error message, verify it is what we get back */ omrstr_printf(knownMessage, 1024, formatMessage1, arg1, arg2); errorCode = omrerror_set_last_error_with_message_format(200, formatMessage1, arg1, arg2); message = omrerror_last_error_message(); if (200 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_set_last_error_with_message() returned %d expected %d\n", errorCode, 200); } if (strlen(message) != strlen(knownMessage)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned length %d expected %d\n", strlen(message), strlen(knownMessage)); } if (0 != memcmp(message, knownMessage, strlen(knownMessage))) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned \"%s\" expected \"%s\"\n", message, knownMessage); } /* Again, different message */ omrstr_printf(knownMessage, 1024, formatMessage2, arg1, arg2); errorCode = omrerror_set_last_error_with_message_format(100, formatMessage2, arg1, arg2); message = omrerror_last_error_message(); if (100 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_set_last_error_with_message() returned %d expected %d\n", errorCode, 100); } if (strlen(message) != strlen(knownMessage)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned length %d expected %d\n", strlen(message), strlen(knownMessage)); } if (0 != memcmp(message, knownMessage, strlen(knownMessage))) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned \"%s\" expected \"%s\"\n", message, knownMessage); } /* Delete the ptBuffers, verify no error is stored */ omrport_tls_free(); errorCode = omrerror_last_error_number(); if (0 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_number() returned %d expected %d\n", errorCode, 0); } reportTestExit(OMRPORTLIB, testName); }
int32_t GCConfigTest::processObjNode(pugi::xml_node node, const char *namePrefixStr, OMRGCObjectType objType, AttributeElem *numOfFieldsElem, AttributeElem *breadthElem, int32_t depth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 1; int32_t numOfParents = 0; /* Create objects and store them in the root table or the slot object based on objType. */ if ((ROOT == objType) || (GARBAGE_ROOT == objType)) { for (int32_t i = 0; i < breadthElem->value; i++) { uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); ObjectEntry *objectEntry = createObject(namePrefixStr, objType, 0, i, sizeCalculated); if (NULL == objectEntry) { goto done; } numOfFieldsElem = numOfFieldsElem->linkNext; /* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/ RootEntry rEntry; rEntry.name = objectEntry->name; rEntry.rootPtr = objectEntry->objPtr; if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) { omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__); goto done; } /* insert garbage per node */ if ((ROOT == objType) && (0 == strcmp(gp.frequency, "perObject"))) { int32_t grt = insertGarbage(); OMRGCTEST_CHECK_RT(grt); } } } else if ((NORMAL == objType) || (GARBAGE_TOP == objType) || (GARBAGE_CHILD == objType)) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0); for (int32_t i = 0; i < breadthElem->value; i++) { uintptr_t sizeCalculated = numOfFieldsElem->value * sizeof(fomrobject_t) + sizeof(uintptr_t); ObjectEntry *childEntry = createObject(namePrefixStr, objType, 0, i, sizeCalculated); if (NULL == childEntry) { goto done; } ObjectEntry *parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } if (0 != attachChildEntry(parentEntry, childEntry)) { goto done; } numOfFieldsElem = numOfFieldsElem->linkNext; /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { int32_t grt = insertGarbage(); OMRGCTEST_CHECK_RT(grt); } } } else { goto done; } /* Create the rest of the tree, if any, defined with depth. First, we set the child object with correct objType. */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } numOfParents = breadthElem->value; breadthElem = breadthElem->linkNext; for (int32_t i = 1; i < depth; i++) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (i - 1), j); for (int32_t k = 0; k < breadthElem->value; k++) { uintptr_t sizeCalculated = sizeof(omrobjectptr_t) + numOfFieldsElem->value * sizeof(fomrobject_t); ObjectEntry *childEntry = createObject(namePrefixStr, objType, i, nthInRow, sizeCalculated); if (NULL == childEntry) { goto done; } ObjectEntry *parentEntry = find(parentName); if (NULL == parentEntry) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } if (0 != attachChildEntry(parentEntry, childEntry)) { goto done; } numOfFieldsElem = numOfFieldsElem->linkNext; nthInRow += 1; /* insert garbage per node */ if ((NORMAL == objType) && (0 == strcmp(gp.frequency, "perObject"))) { int32_t grt = insertGarbage(); OMRGCTEST_CHECK_RT(grt); } } } numOfParents = nthInRow; breadthElem = breadthElem->linkNext; } rt = 0; done: return rt; }
/** * @internal * Generate an IEATDUMP * * @param[in] portLibrary the port library * @param[in,out] asciiLabel the filename to use in ascii. Lowercase letters are _not_ allowed * @param[in,out] ebcdicLabel the filename to use in ebcdic. Lowercase letters are _not_ allowed * @param[out] returnCode the zOS return code from the IEATDUMP call * @param[out] reasonCode the zOS reason code from the IEATDUMP call * * * @return 0 if IEATDUMP was actually called, non-zero if there was an error that prevented us * getting that far * * If we return 0, it's the callers responsibility to check returnCode to find out if the TDUMP was * actually successful * * Note that asciiLabel and ebcdicLabel should represent the same * filename as both are used in this function */ static intptr_t tdump(struct OMRPortLibrary *portLibrary, char *asciiLabel, char *ebcdicLabel, uint32_t *returnCode, uint32_t *reasonCode) { struct ioparms_t { uint64_t plist[256]; uint32_t retcode; uint32_t rsncode; uint32_t retval; } *ioParms31; struct dsn_pattern_t { unsigned char len; char dsn[256]; } *dsnPattern31; /* _TDUMP subroutine expects 31 bit addresses */ ioParms31 = __malloc31(sizeof(*ioParms31)); if (ioParms31 == NULL) { omrtty_err_printf(portLibrary, "__malloc31 failed to allocate buffer for ioParms31\n"); return 1; } memset(ioParms31, 0, sizeof(*ioParms31)); dsnPattern31 = __malloc31(sizeof(*dsnPattern31)); if (dsnPattern31 == NULL) { omrtty_err_printf(portLibrary, "__malloc31 failed to allocate buffer for dsnPattern31\n"); free(ioParms31); return 2; } memset(dsnPattern31, 0, sizeof(*dsnPattern31)); strcpy(dsnPattern31->dsn, ebcdicLabel); dsnPattern31->len = strlen(ebcdicLabel); /* Note: the actual IEATDUMP options are specified on the assembler macro call in omrgenerate_ieat_dumps.s. The * message below needs to be kept consistent with the options set on the macro call. */ omrtty_err_printf(portLibrary, "IEATDUMP in progress with options SDATA=(LPA,GRSQ,LSQA,NUC,PSA,RGN,SQA,SUM,SWA,TRT)\n"); _TDUMP(ioParms31, dsnPattern31); if (returnCode) { *returnCode = ioParms31->retcode; } if (reasonCode) { *reasonCode = ioParms31->rsncode; } if (ioParms31->retcode) { /* * Please refer to VMDESIGN 1459 about IEATDUMP failure recovery */ char errmsg[1024]; omrtty_err_printf(portLibrary, "IEATDUMP failure for DSN='%s' RC=0x%08X RSN=0x%08X\n", asciiLabel, ioParms31->retcode, ioParms31->rsncode); memset(errmsg, 0, sizeof errmsg); omrstr_printf(portLibrary, errmsg, sizeof errmsg, "JVMDMP025I IEATDUMP failed RC=0x%08X RSN=0x%08X DSN=%s", ioParms31->retcode, ioParms31->rsncode, asciiLabel); omrsyslog_write(portLibrary, 0, errmsg); } else { omrtty_err_printf(portLibrary, "IEATDUMP success for DSN='%s'\n", asciiLabel); } free(dsnPattern31); free(ioParms31); return 0; }
void GCConfigTest::TearDown() { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); /* free root table */ hashTableFree(exampleVM->rootTable); /* free object table */ objectTable.free(); /* close verboseManager and clean up verbose files */ verboseManager->closeStreams(env); verboseManager->disableVerboseGC(); verboseManager->kill(env); if (false == gcTestEnv->keepLog) { if (0 == numOfFiles) { J9FileStat buf; int32_t fileStatRC = -1; fileStatRC = omrfile_stat(verboseFile, 0, &buf); if (0 == fileStatRC) { if (1 == buf.isFile) { omrfile_unlink(verboseFile); } } } else { for (int32_t seq = 1; seq <= (int32_t)numOfFiles; seq++) { char verboseFileSeq[MAX_NAME_LENGTH]; omrstr_printf(verboseFileSeq, MAX_NAME_LENGTH, "%s.%03zu", verboseFile, seq); J9FileStat buf; int32_t fileStatRC = -1; fileStatRC = omrfile_stat(verboseFileSeq, 0, &buf); if (0 > fileStatRC) { if (1 != buf.isFile) { break; } } omrfile_unlink(verboseFileSeq); } } } omrmem_free_memory((void *)verboseFile); /* Shut down the dispatcher threads */ omr_error_t rc = OMR_GC_ShutdownDispatcherThreads(exampleVM->_omrVMThread); ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_GC_ShutdownDispatcherThreads failed, rc=" << rc; /* Shut down collector */ rc = OMR_GC_ShutdownCollector(exampleVM->_omrVMThread); ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_GC_ShutdownCollector failed, rc=" << rc; /* Detach from VM */ rc = OMR_Thread_Free(exampleVM->_omrVMThread); ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_Thread_Free failed, rc=" << rc; /* Shut down heap */ rc = OMR_GC_ShutdownHeap(exampleVM->_omrVM); ASSERT_EQ(OMR_ERROR_NONE, rc) << "TearDown(): OMR_GC_ShutdownHeap failed, rc=" << rc; printMemUsed("TearDown()", gcTestEnv->portLib); }
int32_t GCConfigTest::verifyVerboseGC(pugi::xpath_node_set verboseGCs) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; uintptr_t seq = 1; size_t numOfNode = verboseGCs.size(); bool *isFound = (bool *)omrmem_allocate_memory(sizeof(int32_t) * numOfNode, OMRMEM_CATEGORY_MM); if (NULL == isFound) { rt = 1; omrtty_printf("%s:%d Failed to allocate native memory.\n", __FILE__, __LINE__); goto done; } for (size_t i = 0; i < numOfNode; i++) { isFound[i] = false; } /* Loop through multiple files if rolling log is enabled */ do { pugi::xml_document verboseDoc; if (0 == numOfFiles) { verboseDoc.load_file(verboseFile); omrtty_printf("Parsing verbose log %s:\n", verboseFile); #if defined(OMRGCTEST_PRINTFILE) printFile(verboseFile); #endif } else { char currentVerboseFile[MAX_NAME_LENGTH]; omrstr_printf(currentVerboseFile, MAX_NAME_LENGTH, "%s.%03zu", verboseFile, seq++); pugi::xml_parse_result result = verboseDoc.load_file(currentVerboseFile); if (pugi::status_file_not_found == result.status) { break; } omrtty_printf("Parsing verbose log %s:\n", currentVerboseFile); #if defined(OMRGCTEST_PRINTFILE) printFile(currentVerboseFile); #endif } /* verify each xquery criteria */ int32_t i = 0; for (pugi::xpath_node_set::const_iterator it = verboseGCs.begin(); it != verboseGCs.end(); ++it) { const char *xpathNodesStr = it->node().attribute("xpathNodes").value(); const char *xqueryStr = it->node().attribute("xquery").value(); pugi::xpath_query resultQuery(xqueryStr); if (!resultQuery) { rt = 1; omrtty_printf("%s:%d Invalid xquery string \"%s\" specified in configuration file.\n", __FILE__, __LINE__, xqueryStr); goto done; } pugi::xpath_query nodeQuery(xpathNodesStr); if (!nodeQuery) { rt = 1; omrtty_printf("%s:%d Invalid xpathNodes string \"%s\" specified in configuration file.\n", __FILE__, __LINE__, xpathNodesStr); goto done; } pugi::xpath_node_set xpathNodes = nodeQuery.evaluate_node_set(verboseDoc); if (!xpathNodes.empty()) { bool isPassed = true; omrtty_printf("Verifying xquery \"%s\" on xpath \"%s\":\n", xqueryStr, xpathNodesStr); for (pugi::xpath_node_set::const_iterator it = xpathNodes.begin(); it != xpathNodes.end(); ++it) { pugi::xml_node node = it->node(); if (!resultQuery.evaluate_boolean(node)) { rt = 1; isPassed = false; omrtty_printf("\t*FAILED* on node <%s", node.name()); for (pugi::xml_attribute attr = node.first_attribute(); attr; attr = attr.next_attribute()) { omrtty_printf("\t%s=%s", attr.name(), attr.value()); } omrtty_printf(">\n"); } } if (isPassed) { omrtty_printf("*PASSED*\n"); } isFound[i] = true; } i += 1; } omrtty_printf("\n"); } while (seq <= numOfFiles); for (size_t i = 0; i < numOfNode; i++) { if (!isFound[i]) { rt = 1; omrtty_printf("*FAILED* Could not find xpath node \"%s\" in verbose output.\n", verboseGCs[i].node().attribute("xpathNodes").value()); } } done: omrmem_free_memory((void *)isFound); return rt; }
int32_t GCConfigTest::allocationWalker(pugi::xml_node node) { OMRPORT_ACCESS_FROM_OMRVM(exampleVM->_omrVM); int32_t rt = 0; AttributeElem *numOfFieldsElem = NULL; AttributeElem *breadthElem = NULL; int32_t depth = 0; OMRGCObjectType objType = INVALID; const char *namePrefixStr = node.attribute("namePrefix").value(); const char *numOfFieldsStr = node.attribute("numOfFields").value(); const char *typeStr = node.attribute("type").value(); const char *breadthStr = node.attribute("breadth").value(); const char *depthStr = node.attribute("depth").value(); if (0 != strcmp(node.name(), "object")) { /* allow non-object node nested inside allocation? */ goto done; } if ((0 == strcmp(namePrefixStr, "")) || (0 == strcmp(typeStr, "")) || (0 == strcmp(numOfFieldsStr, ""))) { rt = 1; omrtty_printf("%s:%d Invalid XML input: please specify namePrefix, type and numOfFields for object %s.\n", __FILE__, __LINE__, namePrefixStr); goto done; } /* set default value for breadth and depth to 1 */ if (0 == strcmp(breadthStr, "")) { breadthStr = "1"; } if (0 == strcmp(depthStr, "")) { depthStr = "1"; } depth = atoi(depthStr); objType = parseObjectType(node); rt = parseAttribute(&numOfFieldsElem, numOfFieldsStr); OMRGCTEST_CHECK_RT(rt) rt = parseAttribute(&breadthElem, breadthStr); OMRGCTEST_CHECK_RT(rt); /* process current xml node, perform allocation for single object or object tree */ rt = processObjNode(node, namePrefixStr, objType, numOfFieldsElem, breadthElem, depth); OMRGCTEST_CHECK_RT(rt); /* only single object can contain nested child object */ if ((0 == strcmp(breadthStr, "1")) && (0 == strcmp(depthStr, "1"))) { for (pugi::xml_node childNode = node.first_child(); childNode; childNode = childNode.next_sibling()) { rt = allocationWalker(childNode); OMRGCTEST_CHECK_RT(rt); } } /* After the entire garbage tree is allocated, remove garbage root object from the root set * or remove garbage top object from the slot of its parent object. */ if (GARBAGE_ROOT == objType) { for (int32_t i = 0; i < breadthElem->value; i++) { char objName[MAX_NAME_LENGTH]; omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefixStr, 0, i); rt = removeObjectFromRootTable(objName); OMRGCTEST_CHECK_RT(rt); } } else if (GARBAGE_TOP == objType) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, MAX_NAME_LENGTH, "%s_%d_%d", node.parent().attribute("namePrefix").value(), 0, 0); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parentPtr = parentEntry->objPtr; for (int32_t i = 0; i < breadthElem->value; i++) { char objName[MAX_NAME_LENGTH]; omrstr_printf(objName, MAX_NAME_LENGTH, "%s_%d_%d", namePrefixStr, 0, i); rt = removeObjectFromParentSlot(objName, parentPtr); OMRGCTEST_CHECK_RT(rt); } } /* insert garbage per tree */ if ((0 == strcmp(gp.frequency, "perRootStruct")) && (ROOT == objType)){ rt = insertGarbage(); OMRGCTEST_CHECK_RT(rt); } done: freeAttributeList(breadthElem); freeAttributeList(numOfFieldsElem); return rt; }
/* This function takes a thread structure already populated with a backtrace by j9introspect_backtrace_thread * and looks up the symbols for the frames. The format of the string generated is: * symbol_name (statement_id instruction_pointer [module+offset]) * If it isn't possible to determine any of the items in the string then they are omitted. If no heap is specified * then this function will use malloc to allocate the memory necessary for the symbols which must be freed by the caller. * * @param portLbirary a pointer to an initialized port library * @param threadInfo a thread structure populated with a backtrace * @param heap a heap from which to allocate any necessary memory. If NULL malloc is used instead. * * @return the number of frames for which a symbol was constructed. */ uintptr_t omrintrospect_backtrace_symbols_raw(struct OMRPortLibrary *portLibrary, J9PlatformThread *threadInfo, J9Heap *heap) { J9PlatformStackFrame *frame; int i; for (i = 0, frame = threadInfo->callstack; frame != NULL; frame = frame->parent_frame, i++) { char output_buf[512]; char *cursor = output_buf; Dl_info dlInfo; uintptr_t length; uintptr_t iar = frame->instruction_pointer; uintptr_t symbol_offset = 0; uintptr_t module_offset = 0; const char *symbol_name = ""; const char *module_name = "<unknown>"; short symbol_length = 0; memset(&dlInfo, 0, sizeof(Dl_info)); /* do the symbol resolution while we're here */ if (dladdr((void*) iar, &dlInfo)) { if (dlInfo.dli_sname != NULL) { uintptr_t sym = (uintptr_t) dlInfo.dli_saddr; symbol_name = dlInfo.dli_sname; symbol_length = strlen(symbol_name); symbol_offset = iar - (uintptr_t) sym; } if (dlInfo.dli_fname != NULL) { /* strip off the full path if possible */ module_name = strrchr(dlInfo.dli_fname, '/'); if (module_name != NULL) { module_name++; } else { module_name = dlInfo.dli_fname; } } if (dlInfo.dli_fbase != NULL) { /* set the module offset */ module_offset = iar - (uintptr_t) dlInfo.dli_fbase; } } /* sanity check */ if (symbol_name == NULL) { symbol_name = ""; symbol_length = 0; } /* symbol_name+offset (id, instruction_pointer [module+offset]) */ if (symbol_length > 0) { cursor += omrstr_printf(portLibrary, cursor, sizeof(output_buf) - (cursor - output_buf), "%.*s", symbol_length, symbol_name); cursor += omrstr_printf(portLibrary, cursor, sizeof(output_buf) - (cursor - output_buf), "+0x%x ", symbol_offset); } cursor += omrstr_printf(portLibrary, cursor, sizeof(output_buf) - (cursor - output_buf), "(0x%p", frame->instruction_pointer); if (module_name[0] != '\0') { cursor += omrstr_printf(portLibrary, cursor, sizeof(output_buf) - (cursor - output_buf), " [%s+0x%x]", module_name, module_offset); } *(cursor++) = ')'; *cursor = 0; length = (cursor - output_buf) + 1; if (heap != NULL) { frame->symbol = portLibrary->heap_allocate(portLibrary, heap, length); } else { frame->symbol = portLibrary->mem_allocate_memory(portLibrary, length, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_PORT_LIBRARY); } if (frame->symbol != NULL) { strncpy(frame->symbol, output_buf, length); } else { frame->symbol = NULL; if (!threadInfo->error) { threadInfo->error = ALLOCATION_FAILURE; } i--; } } return i; }
int32_t GCConfigTest::createFixedSizeTree(omrobjectptr_t *rootObj, const char *namePrefixStr, OMRGCObjectType objType, uintptr_t totalSize, uintptr_t objSize, int32_t breadth) { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); int32_t rt = 0; OMR_VM *omrVMPtr = exampleVM->_omrVM; int32_t depth = 1; int32_t numOfParents = 1; uintptr_t bytesLeft = totalSize; if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { return rt; } } /* allocate the root object */ char *rootObjName = NULL; rt = createObject(rootObj, &rootObjName, namePrefixStr, objType, 0, 0, objSize); OMRGCTEST_CHECK_RT(rt); bytesLeft -= objSize; /* Add object to root hash table. If it's the root of the garbage tree, temporarily keep it as root for allocating * the rest of the tree. Remove it from the root set after the entire garbage tree is allocated.*/ RootEntry rEntry; rEntry.name = rootObjName; rEntry.rootPtr = *rootObj; if (NULL == hashTableAdd(exampleVM->rootTable, &rEntry)) { rt = 1; omrtty_printf("%s:%d Failed to add new root entry to root table!\n", __FILE__, __LINE__); goto done; } /* create the rest of the tree */ if (ROOT == objType) { objType = NORMAL; } else if ((GARBAGE_TOP == objType) || (GARBAGE_ROOT == objType)) { objType = GARBAGE_CHILD; } while (bytesLeft > 0) { int32_t nthInRow = 0; for (int32_t j = 0; j < numOfParents; j++) { char parentName[MAX_NAME_LENGTH]; omrstr_printf(parentName, sizeof(parentName), "%s_%d_%d", namePrefixStr, (depth - 1), j); ObjectEntry *parentEntry; rt = objectTable.find(&parentEntry, parentName); if (0 != rt) { omrtty_printf("%s:%d Could not find object %s in hash table.\n", __FILE__, __LINE__, parentName); goto done; } omrobjectptr_t parent = parentEntry->objPtr; GC_ObjectIterator objectIterator(omrVMPtr, parent); objectIterator.restore(parentEntry->numOfRef); for (int32_t k = 0; k < breadth; k++) { if (bytesLeft < objSize) { objSize = bytesLeft; if (objSize <= 0) { goto done; } } omrobjectptr_t obj; char *objName = NULL; rt = createObject(&obj, &objName, namePrefixStr, objType, depth, nthInRow, objSize); OMRGCTEST_CHECK_RT(rt); bytesLeft -= objSize; nthInRow += 1; GC_SlotObject *slotObject = NULL; if (NULL != (slotObject = objectIterator.nextSlot())) { #if defined(OMRGCTEST_DEBUG) omrtty_printf("\tadd to parent(%llu) slot %d.\n", parent, parentEntry->numOfRef + k); #endif slotObject->writeReferenceToSlot(obj); } else { rt = 1; omrtty_printf("%s:%d Invalid XML input: numOfFields defined for %s is not enough to hold all children references.\n", __FILE__, __LINE__, parentName); goto done; } } parentEntry->numOfRef += breadth; } numOfParents = nthInRow; depth += 1; } done: return rt; }
void GCConfigTest::SetUp() { OMRPORT_ACCESS_FROM_OMRPORT(gcTestEnv->portLib); printMemUsed("Setup()", gcTestEnv->portLib); /* Initialize heap and collector */ MM_StartupManagerTestExample startupManager(exampleVM->_omrVM, GetParam()); omr_error_t rc = OMR_GC_IntializeHeapAndCollector(exampleVM->_omrVM, &startupManager); ASSERT_EQ(OMR_ERROR_NONE, rc) << "Setup(): OMR_GC_IntializeHeapAndCollector failed, rc=" << rc; /* Attach calling thread to the VM */ exampleVM->_omrVMThread = NULL; rc = OMR_Thread_Init(exampleVM->_omrVM, NULL, &exampleVM->_omrVMThread, "OMRTestThread"); ASSERT_EQ(OMR_ERROR_NONE, rc) << "Setup(): OMR_Thread_Init failed, rc=" << rc; /* Kick off the dispatcher threads */ rc = OMR_GC_InitializeDispatcherThreads(exampleVM->_omrVMThread); ASSERT_EQ(OMR_ERROR_NONE, rc) << "Setup(): OMR_GC_InitializeDispatcherThreads failed, rc=" << rc; env = MM_EnvironmentBase::getEnvironment(exampleVM->_omrVMThread); /* load config file */ omrtty_printf("Configuration File: %s\n", GetParam()); #if defined(OMRGCTEST_PRINTFILE) printFile(GetParam()); #endif pugi::xml_parse_result result = doc.load_file(GetParam()); if (!result) { FAIL() << "Failed to load test configuration file (" << GetParam() << ") with error description: " << result.description() << "."; } /* parse verbose information and initialize verbose manager */ pugi::xml_node optionNode = doc.select_node("/gc-config/option").node(); const char *verboseFileNamePrefix = optionNode.attribute("verboseLog").value(); numOfFiles = (uintptr_t)optionNode.attribute("numOfFiles").as_int(); uintptr_t numOfCycles = (uintptr_t)optionNode.attribute("numOfCycles").as_int(); if (0 == strcmp(verboseFileNamePrefix, "")) { verboseFileNamePrefix = "VerboseGCOutput"; } verboseFile = (char *)omrmem_allocate_memory(MAX_NAME_LENGTH, OMRMEM_CATEGORY_MM); if (NULL == verboseFile) { FAIL() << "Failed to allocate native memory."; } omrstr_printf(verboseFile, MAX_NAME_LENGTH, "%s_%d_%lld.xml", verboseFileNamePrefix, omrsysinfo_get_pid(), omrtime_current_time_millis()); verboseManager = MM_VerboseManager::newInstance(env, exampleVM->_omrVM); verboseManager->configureVerboseGC(exampleVM->_omrVM, verboseFile, numOfFiles, numOfCycles); omrtty_printf("Verbose File: %s\n", verboseFile); #if defined(OMRGCTEST_DEBUG) omrtty_printf("Verbose GC log name: %s; numOfFiles: %d; numOfCycles: %d.\n", verboseFile, numOfFiles, numOfCycles); #endif verboseManager->enableVerboseGC(); verboseManager->setInitializedTime(omrtime_hires_clock()); /* create object table */ objectTable.create(); /* create root table */ exampleVM->rootTable = hashTableNew( gcTestEnv->portLib, OMR_GET_CALLSITE(), 0, sizeof(RootEntry), 0, 0, OMRMEM_CATEGORY_MM, rootTableHashFn, rootTableHashEqualFn, NULL, NULL); }