static int J9THREAD_PROC shutdownTraceHelper(void *entryArg) { omr_error_t rc = OMR_ERROR_NONE; ChildThreadData *childData = (ChildThreadData *)entryArg; OMRTestVM *testVM = childData->testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Init(&testVM->omrVM, NULL, &vmthread, "shutdownTraceHelper")); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } rc = OMRTEST_PRINT_ERROR(omr_ras_cleanupTraceEngine(vmthread)); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } rc = OMRTEST_PRINT_ERROR(OMR_Thread_Free(vmthread)); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } return 0; }
static int J9THREAD_PROC moduleUnloadAfterThreadDetachHelper(void *entryArg) { omr_error_t rc = OMR_ERROR_NONE; ChildThreadData *childData = (ChildThreadData *)entryArg; OMRTestVM *testVM = childData->testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Init(&testVM->omrVM, NULL, &vmthread, "moduleUnloadAfterThreadDetachHelper")); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } UT_OMR_TEST_MODULE_LOADED(testVM->omrVM._trcEngine->utIntf); Trc_OMR_Test_String(vmthread, "This tracepoint should appear."); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Free(vmthread)); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } /* This should fail silently without crashing */ UT_OMR_TEST_MODULE_UNLOADED(testVM->omrVM._trcEngine->utIntf); return 0; }
TEST(TraceLifecycleTest, deregisterSubscriberAfterShutdown) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; UtSubscription *subscriptionID = NULL; const OMR_TI *ti = omr_agent_getTI(); OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", datDir)); /* Attach the thread to the trace engine */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "registerSubscriberAfterShutdown")); /* Register the subscriber */ OMRTEST_ASSERT_ERROR_NONE( ti->RegisterRecordSubscriber(vmthread, "registerSubscriberAfterShutdown", subscribeFunc, NULL, NULL, &subscriptionID)); /* Shut down the trace engine */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); /* Attempt to deregister using external agent API. This succeeds because this thread is still attached to the trace engine. */ OMRTEST_ASSERT_ERROR_NONE(ti->DeregisterRecordSubscriber(vmthread, subscriptionID)); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf); }
TEST(RASMemoryCategoriesTest, Agent) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; const char *agentName = "memorycategoriesagent"; struct OMR_Agent *agent = NULL; OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, rasTestEnv->getPortLibrary())); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "memoryCategoriesTest")); /* load memorycategoriesagent */ agent = omr_agent_create(&testVM.omrVM, agentName); ASSERT_FALSE(NULL == agent) << "createAgent(" << agentName << ") failed"; OMRTEST_ASSERT_ERROR_NONE(omr_agent_openLibrary(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnLoad(agent)); /** The test code is actually in the OnLoadFunction **/ /* Unload the agent */ omr_agent_callOnUnload(agent); omr_agent_destroy(agent); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); }
TEST(TraceLifecycleTest, moduleUnloadAfterThreadDetach) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; omrthread_t childThread = NULL; ChildThreadData *childData = NULL; OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", datDir)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "moduleLoadBeforeThreadAttach")); ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &childThread, moduleUnloadAfterThreadDetachHelper, &childData)); ASSERT_EQ(1, omrthread_resume(childThread)); OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, childThread, childData)); /* Unload the module that was left loaded by the child thread */ UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf); }
TEST(RASTraceOptionTest, TraceOptionAgent) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; /* OMR Trace data structures */ const char *trcOpts = "print=all"; struct OMR_Agent *agent = NULL; OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = NULL; OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "traceOptionTest")); datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, trcOpts, datDir)); OMRTEST_ASSERT_ERROR_NONE(omr_trc_startThreadTrace(vmthread, "initialization thread")); /* load agent */ agent = omr_agent_create(&testVM.omrVM, "traceOptionAgent"); ASSERT_FALSE(NULL == agent) << "testAgent: createAgent() traceOptionAgent failed"; OMRTEST_ASSERT_ERROR_NONE(omr_agent_openLibrary(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnLoad(agent)); /* Initialise the omr_test module for tracing */ UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf); /* Fire some trace points! */ Trc_OMR_Test_Init(); Trc_OMR_Test_Ptr(vmthread, vmthread); Trc_OMR_Test_Int(vmthread, 10); Trc_OMR_Test_Int(vmthread, 99); Trc_OMR_Test_ManyParms(vmthread, "Hello again!", vmthread, 10); UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); /* Unload the agent */ OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnUnload(agent)); omr_agent_destroy(agent); Trc_OMR_Test_String(vmthread, "This tracepoint should be ignored."); OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); }
TEST(TraceLifecycleTest, threadAttachDetachStress) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; const int attachDetachHelpersCount = 10; omrthread_t attachDetachHelpers[attachDetachHelpersCount]; ChildThreadData *attachDetachData[attachDetachHelpersCount]; omrthread_t shutdownHelper = NULL; ChildThreadData *shutdownData = NULL; OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all", datDir)); /* Attach the thread to the trace engine */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "registerSubscriberAfterShutdown")); UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf); /* module is not unloaded before trace engine shutdown */ for (int i = 0; i < attachDetachHelpersCount; i++) { ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &attachDetachHelpers[i], attachDetachHelper, &attachDetachData[i])); } ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &shutdownHelper, shutdownTraceHelper, &shutdownData)); for (int i = 0; i < attachDetachHelpersCount; i++) { ASSERT_EQ(1, omrthread_resume(attachDetachHelpers[i])); } ASSERT_EQ(1, omrthread_resume(shutdownHelper)); for (int i = 0; i < attachDetachHelpersCount; i++) { OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, attachDetachHelpers[i], attachDetachData[i])); } OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, shutdownHelper, shutdownData)); /* Now clear up the VM we started for this test case. */ UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf); }
/* * This test just starts up and shuts down the trace engine. * Run it in a loop to check for memory leaks. */ TEST(TraceLifecycleTest, startupShutdownSanity) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", ".")); /* Attach the thread to the trace engine */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "stub")); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); }
/* * Without ENABLE_BUGS, this test doesn't test anything. */ TEST(TraceLifecycleTest, DISABLE_moduleLoadAfterTraceShutdown) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", datDir)); /* Attach the thread to the trace engine */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "moduleLoadAfterTraceShutdown")); #if ENABLE_BUGS /* cache the UtInterface */ UtInterface *utIntf = testVM.omrVM._trcEngine->utIntf; #endif /* ENABLE_BUGS */ /* Shut down the trace engine */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); ASSERT_TRUE(NULL == vmthread->_vm->utIntf); ASSERT_TRUE(NULL == (void *)testVM.omrVM._trcEngine); #if ENABLE_BUGS /* Attempt to load a module. Note this requires bogus caching of UtInterface*, and using it after it was freed. */ /* moduleLoaded() crashes on attempt to use omrTraceGlobal */ UT_OMR_TEST_MODULE_LOADED(utIntf); Trc_OMR_Test_UnloggedTracepoint(vmthread, "The module was loaded after trace shutdown."); UT_OMR_TEST_MODULE_UNLOADED(utIntf); #endif /* ENABLE_BUGS */ /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf); }
static int J9THREAD_PROC childThreadMain(void *entryArg) { omr_error_t rc = OMR_ERROR_NONE; TestChildThreadData *childData = (TestChildThreadData *)entryArg; OMRTestVM *testVM = childData->testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary); Trc_OMR_Test_String(vmthread, "This tracepoint should be ignored. Trace is not yet enabled for this thread."); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Init(&testVM->omrVM, NULL, &vmthread, "traceTest-child")); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } /* Fire some trace points */ Trc_OMR_Test_Init(); Trc_OMR_Test_String(vmthread, "Child Hello World!"); Trc_OMR_Test_Ptr(vmthread, vmthread); Trc_OMR_Test_Int(vmthread, 10); Trc_OMR_Test_ManyParms(vmthread, "Child Hello again!", vmthread, 10); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Free(vmthread)); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } Trc_OMR_Test_String(vmthread, "This tracepoint should be ignored. Trace has been disabled for this thread."); omrthread_monitor_enter(childData->shutdownCond); childData->isDead = TRUE; omrthread_monitor_notify_all(childData->shutdownCond); omrthread_monitor_exit(childData->shutdownCond); return 0; }
static int J9THREAD_PROC attachDetachHelper(void *entryArg) { omr_error_t rc = OMR_ERROR_NONE; ChildThreadData *childData = (ChildThreadData *)entryArg; OMRTestVM *testVM = childData->testVM; OMR_VMThread *vmthread = NULL; OMRPORT_ACCESS_FROM_OMRPORT(testVM->portLibrary); rc = OMRTEST_PRINT_ERROR(OMR_Thread_Init(&testVM->omrVM, NULL, &vmthread, "attachDetachHelper")); if (OMR_ERROR_NONE != rc) { if (OMR_ERROR_NOT_AVAILABLE == rc) { /* this is ok, it means the shutdown helper finished first */ return 0; } else { childData->childRc = rc; return -1; } } /* yield to encourage concurency */ omrthread_sleep(1); /* Fire some trace points */ const char *alphabetUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; size_t stringsPerTraceBuffer = (1024 + strlen(alphabetUpper) - 1) / strlen(alphabetUpper); for (size_t i = 0; i < stringsPerTraceBuffer * 5; i += 1) { Trc_OMR_Test_String(vmthread, alphabetUpper); omrthread_yield(); } rc = OMRTEST_PRINT_ERROR(OMR_Thread_Free(vmthread)); if (OMR_ERROR_NONE != rc) { childData->childRc = rc; return -1; } return 0; }
TEST(TraceLifecycleTest, moduleLoadBeforeThreadAttach) { /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; const OMR_TI *ti = omr_agent_getTI(); UtSubscription *subscriptionID = NULL; TracePointCounts tpCounts; memset(&tpCounts, 0, sizeof(tpCounts)); tpCounts.osThread = omrthread_self(); initWrapBuffer(&tpCounts.wrapBuffer); OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", datDir)); /* Attempt to load a module before attaching the thread. This should fail silently without crashing */ UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf); /* Attach the thread to the trace engine */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "moduleLoadBeforeThreadAttach")); OMRTEST_ASSERT_ERROR_NONE( ti->RegisterRecordSubscriber(vmthread, "moduleLoadBeforeThreadAttach", countTracepoints, NULL, (void *)&tpCounts, &subscriptionID)); /* Attempt to log a tracepoint. Nothing should happen. */ Trc_OMR_Test_UnloggedTracepoint(vmthread, "The trace module was loaded before the current thread was attached."); #if ENABLE_BUGS /* This can't be done because there is no check for whether the module was actually loaded. */ UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); #endif /* ENABLE_BUGS */ /* This should succeed. */ UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf); Trc_OMR_Test_String(vmthread, "This tracepoint should appear."); UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); /* * Must not deregister before omr_ras_cleanupTraceEngine() because cleanup flushes the trace buffers. * This succeeds for a weird reason: omr_ras_cleanupTraceEngine() actually deregistered all * subscribers when it detached the current thread. This Deregister call does nothing. */ OMRTEST_ASSERT_ERROR_NONE(ti->DeregisterRecordSubscriber(vmthread, subscriptionID)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); /* Validate the number of tracepoints */ ASSERT_EQ(0, tpCounts.unloggedCount); ASSERT_EQ(1, tpCounts.loggedCount); freeWrapBuffer(&tpCounts.wrapBuffer); ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf); }
/* * Tests: * - Attempt to log a tracepoint after trace engine shutdown started. * - Attempt to unload a module after trace engine shutdown started. * * If module unloading fails, this test case tends to cause later tests * to crash because the static omr_test_UtModuleInfo and omr_test_UtActive * structures are left in a polluted state. */ TEST(TraceLifecycleTest, traceAndModuleUnloadAfterTraceShutdown) { const OMR_TI *ti = omr_agent_getTI(); UtSubscription *subscriptionID = NULL; /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; /* child thread data */ omrthread_t shutdownTrcThr = NULL; ChildThreadData *shutdownTrcData = NULL; TracePointCountsMT tpCountsMT; TracePointCounts tpCounts[2]; tpCountsMT.numThreads = 2; tpCountsMT.tpCounts = tpCounts; memset(tpCounts, 0, sizeof(TracePointCounts) * 2); initWrapBuffer(&tpCounts[0].wrapBuffer); initWrapBuffer(&tpCounts[1].wrapBuffer); tpCounts[0].osThread = omrthread_self(); ASSERT_EQ(0, omrthread_monitor_init_with_name(&tpCountsMT.lock, 0, "&tpCountsMT.lock")); OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* use small buffers to exercise buffer wrapping */ OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "buffers=1k:maximal=all:print=omr_test", datDir)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "traceTest")); /* start counting tracepoints */ OMRTEST_ASSERT_ERROR_NONE( ti->RegisterRecordSubscriber(vmthread, "traceAndModuleUnloadAfterTraceShutdown", countTracepointsMT, NULL, (void *)&tpCountsMT, &subscriptionID)); /* Initialise the omr_test module for tracing */ UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf); /* Shut down the trace engine */ ASSERT_NO_FATAL_FAILURE(startChildThread(&testVM, &shutdownTrcThr, shutdownTraceHelper, &shutdownTrcData)); ASSERT_EQ(1, omrthread_resume(shutdownTrcThr)); OMRTEST_ASSERT_ERROR_NONE(waitForChildThread(&testVM, shutdownTrcThr, shutdownTrcData)); /* Attempt to log a tracepoint. It will not be logged. */ Trc_OMR_Test_UnloggedTracepoint(vmthread, "Tracepoint initiated after trace engine shutdown is started."); UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); /* Now clear up the VM we started for this test case. */ /* Stop counting tracepoints */ omr_trc_stopThreadTrace(vmthread); /* flush the thread's trace buffer and delete all subscribers */ OMRTEST_ASSERT_ERROR_NONE(ti->DeregisterRecordSubscriber(vmthread, subscriptionID)); /* do nothing */ OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); ASSERT_EQ(0, tpCounts[0].unloggedCount); ASSERT_EQ(0, tpCounts[0].loggedCount); freeWrapBuffer(&tpCounts[0].wrapBuffer); ASSERT_EQ(0, tpCounts[1].unloggedCount); ASSERT_EQ(0, tpCounts[1].loggedCount); freeWrapBuffer(&tpCounts[1].wrapBuffer); ASSERT_EQ(0, omrthread_monitor_destroy(tpCountsMT.lock)); ASSERT_TRUE(NULL == (void *)omr_test_UtModuleInfo.intf); }
TEST(RASTraceTest, TraceAgent) { struct OMR_Agent *agent = NULL; /* OMR VM data structures */ OMRTestVM testVM; OMR_VMThread *vmthread = NULL; /* child thread data */ omrthread_t childThread = NULL; TestChildThreadData *childData = NULL; OMRPORT_ACCESS_FROM_OMRPORT(rasTestEnv->getPortLibrary()); char *datDir = getTraceDatDir(rasTestEnv->_argc, (const char **)rasTestEnv->_argv); OMRTEST_ASSERT_ERROR_NONE(omrTestVMInit(&testVM, OMRPORTLIB)); /* WARNING: This negative test leaks memory. */ OMRTEST_ASSERT_ERROR(omr_ras_initTraceEngine(&testVM.omrVM, "print=all:duck=quack", datDir), OMR_ERROR_ILLEGAL_ARGUMENT); OMRTEST_ASSERT_ERROR_NONE(omr_ras_initTraceEngine(&testVM.omrVM, "maximal=all", datDir)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Init(&testVM.omrVM, NULL, &vmthread, "traceTest")); #if TEST_TRACEAGENT /* load traceagent */ { agent = omr_agent_create(&testVM.omrVM, "traceagent"); ASSERT_FALSE(NULL == agent) << "testAgent: createAgent() traceagent failed"; OMRTEST_ASSERT_ERROR_NONE(omr_agent_openLibrary(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnLoad(agent)); } #endif /* TEST_TRACEAGENT */ /* Initialise the omr_test module for tracing */ UT_OMR_TEST_MODULE_LOADED(testVM.omrVM._trcEngine->utIntf); /* Fire some trace points! */ Trc_OMR_Test_Init(); Trc_OMR_Test_String(vmthread, "Hello World!"); Trc_OMR_Test_Ptr(vmthread, vmthread); Trc_OMR_Test_Int(vmthread, 10); Trc_OMR_Test_ManyParms(vmthread, "Hello again!", vmthread, 10); /* Fire some trace points in another thread. */ OMRTEST_ASSERT_ERROR_NONE(startTestChildThread(&testVM, vmthread, &childThread, &childData)); OMRTEST_ASSERT_ERROR_NONE(waitForTestChildThread(&testVM, childThread, childData)); /* Confirm that the test worked! */ /* OMRTODO Check something */ UT_OMR_TEST_MODULE_UNLOADED(testVM.omrVM._trcEngine->utIntf); #if TEST_TRACEAGENT /* Unload the traceagent */ OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnUnload(agent)); omr_agent_destroy(agent); #endif /* TEST_TRACEAGENT */ /* Load sampleSubscriber agent */ #if defined(WIN32) agent = omr_agent_create(&testVM.omrVM, "sampleSubscriber=NUL"); #else /* defined(WIN32) */ agent = omr_agent_create(&testVM.omrVM, "sampleSubscriber=/dev/null"); #endif /* defined(WIN32) */ ASSERT_FALSE(NULL == agent) << "testAgent: createAgent() sampleSubscriber failed"; OMRTEST_ASSERT_ERROR_NONE(omr_agent_openLibrary(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnLoad(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnUnload(agent)); omr_agent_destroy(agent); /* Load bindthreadagent agent */ agent = omr_agent_create(&testVM.omrVM, "bindthreadagent"); ASSERT_FALSE(NULL == agent) << "testAgent: createAgent() bindthreadagent failed"; OMRTEST_ASSERT_ERROR_NONE(omr_agent_openLibrary(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnLoad(agent)); OMRTEST_ASSERT_ERROR_NONE(omr_agent_callOnUnload(agent)); omr_agent_destroy(agent); OMRTEST_ASSERT_ERROR_NONE(omr_ras_cleanupTraceEngine(vmthread)); OMRTEST_ASSERT_ERROR_NONE(OMR_Thread_Free(vmthread)); /* Now clear up the VM we started for this test case. */ OMRTEST_ASSERT_ERROR_NONE(omrTestVMFini(&testVM)); }
int testMain(int argc, char ** argv, char **envp) { /* Start up */ OMR_VM_Example exampleVM; OMR_VMThread *omrVMThread = NULL; omrthread_t self = NULL; exampleVM._omrVM = NULL; exampleVM.rootTable = NULL; /* Initialize the VM */ omr_error_t rc = OMR_Initialize(&exampleVM, &exampleVM._omrVM); Assert_MM_true(OMR_ERROR_NONE == rc); /* Recursive omrthread_attach() (i.e. re-attaching a thread that is already attached) is cheaper and less fragile * than non-recursive. If performing a sequence of function calls that are likely to attach & detach internally, * it is more efficient to call omrthread_attach() before the entire block. */ int j9rc = (int) omrthread_attach_ex(&self, J9THREAD_ATTR_DEFAULT); Assert_MM_true(0 == j9rc); /* Initialize root table */ exampleVM.rootTable = hashTableNew( exampleVM._omrVM->_runtime->_portLibrary, OMR_GET_CALLSITE(), 0, sizeof(RootEntry), 0, 0, OMRMEM_CATEGORY_MM, rootTableHashFn, rootTableHashEqualFn, NULL, NULL); /* Initialize heap and collector */ { /* This has to be done in local scope because MM_StartupManager has a destructor that references the OMR VM */ MM_StartupManagerImpl startupManager(exampleVM._omrVM); rc = OMR_GC_IntializeHeapAndCollector(exampleVM._omrVM, &startupManager); } Assert_MM_true(OMR_ERROR_NONE == rc); /* Attach current thread to the VM */ rc = OMR_Thread_Init(exampleVM._omrVM, NULL, &omrVMThread, "GCTestMailThread"); Assert_MM_true(OMR_ERROR_NONE == rc); /* Kick off the dispatcher therads */ rc = OMR_GC_InitializeDispatcherThreads(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); OMRPORT_ACCESS_FROM_OMRVM(exampleVM._omrVM); omrtty_printf("VM/GC INITIALIZED\n"); /* Do stuff */ MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(omrVMThread); MM_ObjectAllocationInterface *allocationInterface = env->_objectAllocationInterface; MM_GCExtensionsBase *extensions = env->getExtensions(); omrtty_printf("configuration is %s\n", extensions->configuration->getBaseVirtualTypeId()); omrtty_printf("collector interface is %s\n", env->getExtensions()->collectorLanguageInterface->getBaseVirtualTypeId()); omrtty_printf("garbage collector is %s\n", env->getExtensions()->getGlobalCollector()->getBaseVirtualTypeId()); omrtty_printf("allocation interface is %s\n", allocationInterface->getBaseVirtualTypeId()); /* Allocate objects without collection until heap exhausted */ uintptr_t allocatedFlags = 0; uintptr_t size = extensions->objectModel.adjustSizeInBytes(24); MM_AllocateDescription mm_allocdescription(size, allocatedFlags, true, true); uintptr_t allocatedCount = 0; while (true) { omrobjectptr_t obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), false); if (NULL != obj) { extensions->objectModel.setObjectSize(obj, mm_allocdescription.getBytesRequested()); RootEntry rEntry = {"root1", obj}; RootEntry *entryInTable = (RootEntry *)hashTableAdd(exampleVM.rootTable, &rEntry); if (NULL == entryInTable) { omrtty_printf("failed to add new root to root table!\n"); } /* update entry if it already exists in table */ entryInTable->rootPtr = obj; allocatedCount++; } else { break; } } /* Print/verify thread allocation stats before GC */ MM_AllocationStats *allocationStats = allocationInterface->getAllocationStats(); omrtty_printf("thread allocated %d tlh bytes, %d non-tlh bytes, from %d allocations before NULL\n", allocationStats->tlhBytesAllocated(), allocationStats->nontlhBytesAllocated(), allocatedCount); uintptr_t allocationTotalBytes = allocationStats->tlhBytesAllocated() + allocationStats->nontlhBytesAllocated(); uintptr_t allocatedTotalBytes = size * allocatedCount; Assert_MM_true(allocatedTotalBytes == allocationTotalBytes); /* Force GC to print verbose system allocation stats -- should match thread allocation stats from before GC */ omrobjectptr_t obj = (omrobjectptr_t)allocationInterface->allocateObject(env, &mm_allocdescription, env->getMemorySpace(), true); env->unwindExclusiveVMAccessForGC(); Assert_MM_false(NULL == obj); extensions->objectModel.setObjectSize(obj, mm_allocdescription.getBytesRequested()); omrtty_printf("ALL TESTS PASSED\n"); /* Shut down */ /* Shut down the dispatcher therads */ rc = OMR_GC_ShutdownDispatcherThreads(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); /* Shut down collector */ rc = OMR_GC_ShutdownCollector(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); /* Detach from VM */ rc = OMR_Thread_Free(omrVMThread); Assert_MM_true(OMR_ERROR_NONE == rc); /* Shut down heap */ rc = OMR_GC_ShutdownHeap(exampleVM._omrVM); Assert_MM_true(OMR_ERROR_NONE == rc); /* Free root hash table */ hashTableFree(exampleVM.rootTable); /* Balance the omrthread_attach_ex() issued above */ omrthread_detach(self); /* Shut down VM * This destroys the port library and the omrthread library. * Don't use any port library or omrthread functions after this. * * (This also shuts down trace functionality, so the trace assertion * macros might not work after this.) */ rc = OMR_Shutdown(exampleVM._omrVM); Assert_MM_true(OMR_ERROR_NONE == rc); return rc; }
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); }