/** * Wait for expected event and optionally bring event related data back. * * @param testName The name of the waiting thread * @param info The pointer to SigMaskTestInfo object * @param event The expected event * @param result The event related data * @param size The size of the event data * @return TRUE upon success; FALSE if expected event did not occur before timeout. */ static BOOLEAN waitForEvent(const char *testName, SigMaskTestInfo *info, SignalEvent event, void *result, size_t size) { OMRPORT_ACCESS_FROM_OMRPORT(info->portLibrary); BOOLEAN ret = FALSE; intptr_t waitRC = J9THREAD_WOULD_BLOCK; omrthread_monitor_enter(info->monitor); while (info->bulletinBoard.event != event) { waitRC = omrthread_monitor_wait_timed(info->monitor, 60000, 0); if (J9THREAD_TIMED_OUT == waitRC) { break; } } ret = (info->bulletinBoard.event == event); if (TRUE == ret) { if ((NULL != result) && (size > 0)) { memcpy(result, &info->bulletinBoard.data, size); } } else { if (J9THREAD_TIMED_OUT == waitRC) { outputErrorMessage(PORTTEST_ERROR_ARGS, "timed out without being notified. expected (%d), received (%d)\n", event, info->bulletinBoard.event); } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "expected event(%d) was not received. bulletinBoard(%d)\n", event, info->bulletinBoard.event); } } info->bulletinBoard.event = INVALID; omrthread_monitor_exit(info->monitor); return ret; }
VncView::VncView(QWidget *parent, const KUrl &url, KConfigGroup configGroup) : RemoteView(parent), m_initDone(false), m_buttonMask(0), m_repaint(false), m_quitFlag(false), m_firstPasswordTry(true), m_dontSendClipboard(false), m_horizontalFactor(1.0), m_verticalFactor(1.0), m_forceLocalCursor(false) { m_url = url; m_host = url.host(); m_port = url.port(); // BlockingQueuedConnection can cause deadlocks when exiting, handled in startQuitting() connect(&vncThread, SIGNAL(imageUpdated(int,int,int,int)), this, SLOT(updateImage(int,int,int,int)), Qt::BlockingQueuedConnection); connect(&vncThread, SIGNAL(gotCut(QString)), this, SLOT(setCut(QString)), Qt::BlockingQueuedConnection); connect(&vncThread, SIGNAL(passwordRequest(bool)), this, SLOT(requestPassword(bool)), Qt::BlockingQueuedConnection); connect(&vncThread, SIGNAL(outputErrorMessage(QString)), this, SLOT(outputErrorMessage(QString))); m_clipboard = QApplication::clipboard(); connect(m_clipboard, SIGNAL(dataChanged()), this, SLOT(clipboardDataChanged())); #ifndef QTONLY m_hostPreferences = new VncHostPreferences(configGroup, this); #else Q_UNUSED(configGroup); #endif }
/** * Verify port library management. * * The port library allocates resources as part of it's normal running. Thus * prior to terminating the application the port library must free all it's * resource via the port library table function * @ref omrport.c::omrport_shutdown_library "omrport_shutdown_library()" * * @note self allocated port libraries de-allocate their memory as part of this * function. */ TEST(PortTest, port_test6) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test6"; OMRPortLibrary *fakePtr; int32_t rc; omrthread_t attachedThread = NULL; reportTestEntry(OMRPORTLIB, testName); if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "Failed to attach to omrthread\n"); goto exit; } memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary)); fakePtr = &portLibraryToTest; rc = omrport_init_library(fakePtr, sizeof(OMRPortLibrary)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_init_library() returned %d expected 0\n", rc); } /* Shut it down */ portLibraryToTest.port_shutdown_library(fakePtr); omrthread_detach(attachedThread); /* Global pointer should be NULL */ if (NULL != fakePtr->portGlobals) { outputErrorMessage(PORTTEST_ERROR_ARGS, "port_shutdown_library() portGlobal pointer is not NULL\n"); } /* Shutdown again, should be ok, nothing to check ... * TODO support this? portLibraryToTest.port_shutdown_library(fakePtr); */ /* Let's do it all over again, this time self allocated * Note a self allocated library does not startup, so there are no * port globals etc. Verifies the shutdown routines are safe */ fakePtr = NULL; rc = omrport_allocate_library(&fakePtr); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned %d expected 0\n", rc); goto exit; } /* TODO library not started, fair to shut it down ? fakePtr->port_shutdown_library(fakePtr); */ fakePtr = NULL; exit: reportTestExit(OMRPORTLIB, testName); }
VncView::~VncView() { unpressModifiers(); // Disconnect all signals so that we don't get any more callbacks from the client thread disconnect(&vncThread, SIGNAL(imageUpdated(int, int, int, int)), this, SLOT(updateImage(int, int, int, int))); disconnect(&vncThread, SIGNAL(gotCut(const QString&)), this, SLOT(setCut(const QString&))); disconnect(&vncThread, SIGNAL(passwordRequest()), this, SLOT(requestPassword())); disconnect(&vncThread, SIGNAL(outputErrorMessage(QString)), this, SLOT(outputErrorMessage(QString))); startQuitting(); }
/** * Check that the file exists on the file system. * * This takes the porttest filename and line number information so that the caller is properly identified as failing. * * @param[in] portLibrary The port library * @param[in] fileName File requesting file check * @param[in] lineNumber Line number in the file of request * @param[in] testName Name of the test requesting file check * @param[in] fileName file who's existence we need to verify * @param[in] lineNumber Line number in the file of request * * @return 0 if the file exists, non-zero otherwise. */ uintptr_t verifyFileExists(struct OMRPortLibrary *portLibrary, const char *pltestFileName, int32_t lineNumber, const char *testName, const char *fileName) { uintptr_t rc = 1; OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); portTestEnv->changeIndent(1); #if defined(J9ZOS390) char dumpName[EsMaxPath] = {0}; /* Replace trailing ".X&DS" on 64bit and add required "//" prefix */ strncpy(dumpName, "//", 2); strncat(dumpName, (strstr(fileName, ".") + 1), strlen(fileName)); char *ending = strstr(dumpName, ".X&DS"); if (NULL != ending) { strncpy(ending, ".X001", 5); } portTestEnv->log("checking for data set: %s\n", dumpName); FILE *file = fopen(dumpName, "r"); if (NULL == file) { outputErrorMessage(OMRPORTLIB, pltestFileName, lineNumber, testName, "\tdata set: %s does not exist!\n", -1, fileName); } else { portTestEnv->log("data set: %s exists\n", dumpName); fclose(file); rc = 0; } #else /* defined(J9ZOS390) */ J9FileStat fileStat; int32_t fileStatRC = 99; /* stat the fileName */ fileStatRC = omrfile_stat(fileName, 0, &fileStat); if (0 == fileStatRC) { if (fileStat.isFile) { portTestEnv->log("file: %s exists\n", fileName); rc = 0; } else { outputErrorMessage(OMRPORTLIB, pltestFileName, lineNumber, testName, "\tfile: %s does not exist!\n", -1, fileName); } } else { /* error in file_stat */ outputErrorMessage(OMRPORTLIB, pltestFileName, lineNumber, testName, "\nomrfile_stat call in verifyFileExists() returned %i: %s\n", fileStatRC, omrerror_last_error_message()); } #endif /* defined(J9ZOS390) */ portTestEnv->changeIndent(-1); return rc; }
static uintptr_t simpleHandlerFunction(struct OMRPortLibrary *portLibrary, uint32_t gpType, void *gpInfo, void *handler_arg) { OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); simpleHandlerInfo *info = (simpleHandlerInfo *)handler_arg; const char *testName = info->testName; uintptr_t rc; portTestEnv->log("calling omrdump_create with filename: %s\n", info->coreFileName); #if defined(J9ZOS390) rc = omrdump_create(info->coreFileName, "IEATDUMP", NULL); #else rc = omrdump_create(info->coreFileName, NULL, NULL); #endif if (rc == 0) { uintptr_t verifyFileRC = 99; portTestEnv->log("omrdump_create claims to have written a core file to: %s\n", info->coreFileName); verifyFileRC = verifyFileExists(PORTTEST_ERROR_ARGS, info->coreFileName); if (verifyFileRC == 0) { removeDump(OMRPORTLIB, info->coreFileName, testName); } } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrdump_create returned: %u, with filename: %s", rc, info->coreFileName); } return OMRPORT_SIG_EXCEPTION_RETURN; }
static void removeDump(OMRPortLibrary *portLib, const char *filename, const char *testName) { OMRPORT_ACCESS_FROM_OMRPORT(portLib); bool removeDumpSucceeded = true; portTestEnv->changeIndent(1); /* Delete the file if possible. */ #if defined(J9ZOS390) char deleteCore[EsMaxPath] = {0}; sprintf(deleteCore, "tso delete %s", (strstr(filename, ".") + 1)); char *ending = strstr(deleteCore, ".X&DS"); if (NULL != ending) { strncpy(ending, ".X001", 5); } if (-1 == system(deleteCore)) { removeDumpSucceeded = false; } #else /* defined(J9ZOS390) */ if (0 != remove(filename)) { removeDumpSucceeded = false; } #endif /* defined(J9ZOS390) */ if (removeDumpSucceeded) { portTestEnv->log("removed: %s\n", filename); } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "\tfailed to remove %s\n", filename); } portTestEnv->changeIndent(-1); }
/** * Call omrdump_create() without passing in core file name. This does not actually test that a core file was actually created. */ TEST(PortDumpTest, dump_test_create_dump_with_NO_name) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrdump_test_create_dump_with_NO_name"; uintptr_t rc = 99; char coreFileName[EsMaxPath]; BOOLEAN doFileVerification = FALSE; #if defined(AIXPPC) struct vario myvar; int sys_parmRC; #endif reportTestEntry(OMRPORTLIB, testName); coreFileName[0] = '\0'; #if 0 /* try out a NULL test (turns out this crashes) */ rc = omrdump_create(NULL, NULL, NULL); /* this crashes */ #endif /* try out a more sane NULL test */ portTestEnv->log("calling omrdump_create with empty filename\n"); #if defined(J9ZOS390) rc = omrdump_create(coreFileName, "IEATDUMP", NULL); #else rc = omrdump_create(coreFileName, NULL, NULL); #endif if (rc == 0) { uintptr_t verifyFileRC = 99; portTestEnv->log("omrdump_create claims to have written a core file to: %s\n", coreFileName); #if defined(AIXPPC) /* We defer to fork abort on AIX machines that don't have "Enable full CORE dump" enabled in smit, * in which case omrdump_create will not return the filename. * So, only check for a specific filename if we are getting full core dumps */ sys_parmRC = sys_parm(SYSP_GET, SYSP_V_FULLCORE, &myvar); if ((sys_parmRC == 0) && (myvar.v.v_fullcore.value == 1)) { doFileVerification = TRUE; } #else /* defined(AIXPPC) */ doFileVerification = TRUE; #endif /* defined(AIXPPC) */ if (doFileVerification) { verifyFileRC = verifyFileExists(PORTTEST_ERROR_ARGS, coreFileName); if (verifyFileRC == 0) { removeDump(OMRPORTLIB, coreFileName, testName); } } } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrdump_create returned: %u, with filename: %s", rc, coreFileName); } reportTestExit(OMRPORTLIB, testName); }
void VncClientThread::checkOutputErrorMessage() { if (!outputErrorMessageString.isEmpty()) { QString errorMessage = outputErrorMessageString; outputErrorMessageString.clear(); // show authentication failure error only after the 3rd unsuccessful try if ((errorMessage != i18n("VNC authentication failed.")) || m_passwordError) emit outputErrorMessage(errorMessage); } }
/** * Test calling omrdump_create() from a signal handler. * * Verify that the returned core file name actually exists. */ TEST(PortDumpTest, dump_test_create_dump_from_signal_handler) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrdump_test_create_dump_from_signal_handler"; char buff[EsMaxPath]; char *coreFileName = NULL; uintptr_t result; uint32_t protectResult; simpleHandlerInfo handlerInfo; uint32_t sig_protectFlags; #if defined(J9ZOS390) coreFileName = atoe_getcwd(buff, EsMaxPath); #else coreFileName = getcwd(buff, EsMaxPath); #endif strncat(coreFileName, "/", EsMaxPath); /* make sure the directory ends with a slash */ strncat(coreFileName, testName, EsMaxPath); sig_protectFlags = OMRPORT_SIG_FLAG_SIGSEGV | OMRPORT_SIG_FLAG_MAY_RETURN; reportTestEntry(OMRPORTLIB, testName); if (!omrsig_can_protect(sig_protectFlags)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->sig_protect does not offer adequate protection for test\n"); } else { handlerInfo.coreFileName = coreFileName; handlerInfo.testName = testName; protectResult = omrsig_protect( raiseSEGV, NULL, simpleHandlerFunction, &handlerInfo, sig_protectFlags, &result); if (protectResult != OMRPORT_SIG_EXCEPTION_OCCURRED) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->sig_protect -- expected 0 return value\n"); } } reportTestExit(OMRPORTLIB, testName); }
/** * Verify port library management. * * Ensure the port library is properly setup to run port library maintenance tests. * * Most operations being tested are not stored in the port library table * as they are required for port library allocation, startup and shutdown. * There are a couple to look up. */ TEST(PortTest, port_test0) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test0"; reportTestEntry(OMRPORTLIB, testName); /* Verify that the omrport function pointers are non NULL */ /* omrport_test7 */ if (NULL == OMRPORTLIB->port_shutdown_library) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->port_shutdown_library is NULL\n"); } /* omrport_test9 */ if (NULL == OMRPORTLIB->port_isFunctionOverridden) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->port_isFunctionOverridden is NULL\n"); } reportTestExit(OMRPORTLIB, testName); }
/** * Verify port library management. * * The JIT needs to verify that the function it wants to optimize is what * it expects, that is an application has not provided it's own implementation. * The port library table function * @ref omrport.c::omrport_isFunctionOverridden "omrport_isFunctionOverridden" * is used for this purpose. */ TEST(PortTest, port_test7) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test7"; OMRPortLibrary *fakePtr = &portLibraryToTest; int32_t rc; reportTestEntry(OMRPORTLIB, testName); memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary)); rc = omrport_init_library(&portLibraryToTest, sizeof(OMRPortLibrary)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_init_library() returned %d expected 0\n", rc); } /* override a couple of function */ fakePtr->mem_startup = fake_mem_startup; fakePtr->mem_shutdown = NULL; fakePtr->time_hires_clock = NULL; fakePtr->time_startup = fakePtr->tty_startup; rc = fakePtr->port_isFunctionOverridden(fakePtr, offsetof(OMRPortLibrary, mem_startup)); if (1 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_isFunctionOverridden returned %d expected 1\n", rc); } rc = fakePtr->port_isFunctionOverridden(fakePtr, offsetof(OMRPortLibrary, mem_shutdown)); if (1 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_isFunctionOverridden returned %d expected 1\n", rc); } rc = fakePtr->port_isFunctionOverridden(fakePtr, offsetof(OMRPortLibrary, time_hires_clock)); if (1 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_isFunctionOverridden returned %d expected 1\n", rc); } rc = fakePtr->port_isFunctionOverridden(fakePtr, offsetof(OMRPortLibrary, time_startup)); if (1 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_isFunctionOverridden returned %d expected 1\n", rc); } rc = fakePtr->port_isFunctionOverridden(fakePtr, offsetof(OMRPortLibrary, time_hires_frequency)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_isFunctionOverridden returned %d expected 0\n", rc); } rc = fakePtr->port_isFunctionOverridden(fakePtr, offsetof(OMRPortLibrary, tty_printf)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_isFunctionOverridden returned %d expected 0\n", rc); } reportTestExit(OMRPORTLIB, testName); }
/** * Verify port library memory management. * * Ensure the port library is properly setup to run core file generation operations. */ TEST(PortDumpTest, dump_verify_functiontable_slots) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrdump_verify_functiontable_slots"; reportTestEntry(OMRPORTLIB, testName); /* omrmem_test2 */ if (NULL == OMRPORTLIB->dump_create) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->vmem_reserve_memory is NULL\n"); } reportTestExit(OMRPORTLIB, testName); }
/** * @internal * Verify OMRPortLibrary structure. * * Given a port library structure, verify that it is correctly setup. * * @param[in] portLibrary the port library to verify * @param[in] testName test requesting creation * @param[in] version the version of port library to verify * @param[in] size the expected size */ static void verifyCreateTableContents(struct OMRPortLibrary *portLibrary, const char *testName, uintptr_t size) { OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); omrport_getSize(); /* portGlobals should not be allocated */ if (NULL != OMRPORTLIB->portGlobals) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() portGlobals pointer is not NULL\n"); } /* Not self allocated */ if (NULL != OMRPORTLIB->self_handle) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() self_handle pointer is not NULL\n"); } /* Verify the pointers look correct, must skip version and portGlobals portion information */ /* reach into the port library for the various values of interest */ if (NULL == OMRPORTLIB->tty_printf) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() tty_printf pointer is NULL\n"); } }
/** * Create a J9Thread to carry on test operation * * @param entpoint The entry point of the newly created thread * @param entarg The argument for the entry point function * @return pointer to a J9Thread on success; otherwise, a NULL pointer and log error message */ static omrthread_t create_thread(struct OMRPortLibrary *portLibrary, omrthread_entrypoint_t entpoint, void *entarg) { OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); SigMaskTestInfo *info = (SigMaskTestInfo *)entarg; const char *testName = info->testName; omrthread_t handle = NULL; intptr_t ret = omrthread_create_ex(&handle, J9THREAD_ATTR_DEFAULT, 0, entpoint, entarg); if (J9THREAD_SUCCESS != ret) { outputErrorMessage(PORTTEST_ERROR_ARGS, "failed to create omrthread, returned:%d\n", ret); } return handle; }
/** * Verify port library management. * * Prior to starting a port library the initial values for the function pointers * in the table need to be initialized. The ability to initialize the table with * default values prior to starting the port library allows applications to override * functionality. For example an application may with to control all memory management, * so overriding the appropriate functions is required prior to any memory being * allocated. Creation of the port library table is done via the function * @ref omrport.c::omrport_create_library "omrport_create_library()" * * @see omrport.c::omrport_startup_library "omrport_startup_library()" * @see omrport.c::omrport_init_library "omrport_init_library()" */ TEST(PortTest, port_test2) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test2"; OMRPortLibrary *fakePtr = (OMRPortLibrary *)bigBuffer; char eyeCatcher; int32_t rc; reportTestEntry(OMRPORTLIB, testName); /* Pass, buffer bigger than required */ eyeCatcher = '1'; memset(fakePtr, eyeCatcher, bigBufferSize); rc = omrport_create_library(fakePtr, 2 * sizeof(OMRPortLibrary)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected %d\n", rc); } verifyCreateTableContents(fakePtr, testName, sizeof(OMRPortLibrary)); /* Pass, should create a library equal to that currently running */ eyeCatcher = '2'; memset(fakePtr, eyeCatcher, bigBufferSize); rc = omrport_create_library(fakePtr, sizeof(OMRPortLibrary)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected 0\n", rc); } /* Fail, buffer 1 byte too small */ eyeCatcher = '3'; memset(fakePtr, eyeCatcher, bigBufferSize); rc = omrport_create_library(fakePtr, sizeof(OMRPortLibrary) - 1); if (OMRPORT_ERROR_INIT_OMR_WRONG_SIZE != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected %d\n", rc, OMRPORT_ERROR_INIT_OMR_WRONG_SIZE); } /* Ensure we didn't write anything, being lazy only checking first byte */ if (eyeCatcher != bigBuffer[0]) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() trampled memory expected \"%c\" found \"%c\"\n", eyeCatcher, bigBuffer[0]); } /* Fail, buffer size way too small */ eyeCatcher = '4'; memset(fakePtr, eyeCatcher, bigBufferSize); rc = omrport_create_library(fakePtr, 20); if (OMRPORT_ERROR_INIT_OMR_WRONG_SIZE != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected %d\n", rc, OMRPORT_ERROR_INIT_OMR_WRONG_SIZE); } /* Ensure we didn't write anything, being lazy only checking first byte */ if (eyeCatcher != bigBuffer[0]) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() trampled memory expected \"%c\" found \"%c\"\n", eyeCatcher, bigBuffer[0]); } reportTestExit(OMRPORTLIB, testName); }
/** * Verify port library management. * * Applications wishing to self allocate the port library are required to provide * a size for the port library to create. The size of any port library version can * be obtained via the exported function * @ref omrport.c::omrport_getSize "omrport_getSize()" */ TEST(PortTest, port_test1) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test1"; uintptr_t expectedSize; uintptr_t actualSize; /* First all supported versions */ expectedSize = sizeof(OMRPortLibrary); /* Pass, exact match all fields */ actualSize = omrport_getSize(); if (actualSize != expectedSize) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_getSize() returned %zu expected %zu\n", actualSize, expectedSize); } reportTestExit(OMRPORTLIB, testName); }
/** * Verify port library error handling operations. * * Ensure the library table is properly setup to run error handling tests. */ TEST(PortErrorTest, error_test0) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrerror_test0"; reportTestEntry(OMRPORTLIB, testName); /* Verify that the error handling function pointers are non NULL */ /* Not tested, implementation dependent. No known functionality. * Startup is private to the portlibary, it is not re-entrant safe */ if (NULL == OMRPORTLIB->error_startup) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_startup is NULL\n"); } /* Not tested, implementation dependent. No known functionality */ if (NULL == OMRPORTLIB->error_shutdown) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_shutdown is NULL\n"); } /* omrerror_test1 */ if (NULL == OMRPORTLIB->error_last_error_number) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_last_error_number is NULL\n"); } /* omrerror_test2 */ if (NULL == OMRPORTLIB->error_last_error_message) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_last_error_message is NULL\n"); } /* omrerror_test1 */ if (NULL == OMRPORTLIB->error_set_last_error) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_set_last_error is NULL\n"); } /* omrerror_test2 */ if (NULL == OMRPORTLIB->error_set_last_error_with_message) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_set_last_error_with_message is NULL\n"); } if (NULL == OMRPORTLIB->error_set_last_error_with_message_format) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->error_set_last_error_with_message_format is NULL\n"); } reportTestExit(OMRPORTLIB, testName); }
/** * 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 "omrerror_set_last_error()" are recorded in the per thread * buffers without an error message. * Verify the @ref omrerror_last_error_number "omrerror_last_error_number()" returns * the correct portable error code. */ TEST(PortErrorTest, error_test1) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrerror_test1"; 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 */ errorCode = omrerror_last_error_number(); if (0 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_number() returned %d expected %d\n", errorCode, 0); } /* Set an error code, verify it is what we get back */ errorCode = omrerror_set_last_error(100, 200); if (200 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_set_last_error() returned %d expected %d\n", errorCode, 200); } errorCode = omrerror_last_error_number(); if (200 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_number() returned %d expected %d\n", errorCode, 200); } /* Again with negative values */ errorCode = omrerror_set_last_error(100, -200); if (-200 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_set_last_error() returned %d expected %d\n", errorCode, 200); } errorCode = omrerror_last_error_number(); if (-200 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_number() returned %d expected %d\n", errorCode, 200); } /* 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); }
/** * Test omrdump_create(), this time passing in core file name * Verify that the returned core file name actually exists. * * @note this only tests IEATDUMP generation on z/OS */ TEST(PortDumpTest, dump_test_create_dump_with_name) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrdump_test_create_dump_with_name"; uintptr_t rc = 99; char buff[EsMaxPath]; char *coreFileName = NULL; reportTestEntry(OMRPORTLIB, testName); #if defined(J9ZOS390) coreFileName = atoe_getcwd(buff, EsMaxPath); #else coreFileName = getcwd(buff, EsMaxPath); #endif strncat(coreFileName, "/", EsMaxPath); /* make sure the directory ends with a slash */ strncat(coreFileName, testName, EsMaxPath); portTestEnv->log("calling omrdump_create with filename: %s\n", coreFileName); #if !defined(J9ZOS390) rc = omrdump_create(coreFileName, NULL, NULL); #else rc = omrdump_create(coreFileName, "IEATDUMP", NULL); #endif if (rc == 0) { uintptr_t verifyFileRC = 99; portTestEnv->log("omrdump_create claims to have written a core file to: %s\n", coreFileName); verifyFileRC = verifyFileExists(PORTTEST_ERROR_ARGS, coreFileName); if (verifyFileRC == 0) { removeDump(OMRPORTLIB, coreFileName, testName); } } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrdump_create returned: %u, with filename: %s\n", rc, coreFileName); } reportTestExit(OMRPORTLIB, testName); }
uintptr_t raiseSEGV(OMRPortLibrary *portLibrary, void *arg) { OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); const char *testName = (const char *)arg; #if defined(WIN32) || defined (J9ZOS390) /* * - Windows structured exception handling doesn't interact with raise(). * - z/OS doesn't provide a value for the psw1 (PC) register when you use raise() */ char *ptr = (char *)(-1); ptr -= 4; *ptr = -1; #else raise(SIGSEGV); #endif outputErrorMessage(PORTTEST_ERROR_ARGS, "unexpectedly continued execution"); return 8096; }
/** * Verify port library management. * * The second stage in starting a port library. Once a port library table has * been created via * @ref omrport.c::omrport_create_library "omrport_create_library()" * it is started via the exported function * @ref omrport.c::omrport_startup_library "omrport_startup_library()". * * @see omrport.c::omrport_create_library "omrport_create_library()" * @see omrport.c::omrport_init_library "omrport_init_library()" */ TEST(PortTest, port_test3) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test3"; OMRPortLibrary *fakePtr = &portLibraryToTest; int32_t rc; omrthread_t attachedThread = NULL; reportTestEntry(OMRPORTLIB, testName); if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "Failed to attach to omrthread\n"); goto exit; } /* create a library and ensure the port globals is non NULL, what else can we do? */ memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary)); rc = omrport_create_library(fakePtr, sizeof(OMRPortLibrary)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected 0\n", rc); goto exit; } /* check the rc */ rc = omrport_startup_library(fakePtr); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected 0\n", rc); } /* check portGlobals were allocated */ if (NULL == fakePtr->portGlobals) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() portGlobals not allocated\n"); } if (NULL != fakePtr->self_handle) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() self_handle pointer not NULL\n"); } /* Clean this port library up */ portLibraryToTest.port_shutdown_library(fakePtr); /* Do it again, but before starting override memory (first startup function) and * ensure everything is ok */ memset(&portLibraryToTest, '0', sizeof(OMRPortLibrary)); rc = omrport_create_library(fakePtr, sizeof(OMRPortLibrary)); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_create_library() returned %d expected 0\n", rc); goto exit; } /* override time_startup */ fakePtr->time_startup = fake_time_startup; rc = omrport_startup_library(fakePtr); if (failMemStartup != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected %d\n", rc, failMemStartup); } exit: portLibraryToTest.port_shutdown_library(fakePtr); if (NULL != attachedThread) { omrthread_detach(attachedThread); } reportTestExit(OMRPORTLIB, testName); }
/** * 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); }
/** * 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 "omrerror_set_last_error_with_message()" * 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_test2) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrerror_test2"; const char *message; const char *knownMessage = "This is a test"; const char *knownMessage2 = "This is also a test"; 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 */ errorCode = omrerror_set_last_error_with_message(200, knownMessage); 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 */ errorCode = omrerror_set_last_error_with_message(100, knownMessage2); 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(knownMessage2)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned length %d expected %d\n", strlen(message), strlen(knownMessage2)); } if (0 != memcmp(message, knownMessage2, strlen(knownMessage2))) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned \"%s\" expected \"%s\"\n", message, knownMessage2); } /* A null message, valid test?*/ #if 0 errorCode = omrerror_set_last_error_with_message(-100, NULL); message = omrerror_last_error_message(); if (-100 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned %d expected %d\n", errorCode, -100); } if (NULL != message) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_message() returned \"%s\" expected NULL\n", message); } #endif omrport_tls_free(); errorCode = omrerror_set_last_error_with_message(-300, knownMessage); message = omrerror_last_error_message(); if (-300 != errorCode) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrerror_last_error_number() returned %d expected %d\n", errorCode, -300); } 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); }
/** * Verify port library management. * * The port library requires a region of memory for it's function table pointer. * This table must not be declared on a stack that is torn down prior to the application * running to completion and tearing down the port library. It can either be * created as a global variable to the program, or if a running port library is * present it can be allocated on behalf of the application. Self allocating * port libraries use the exported function * @ref omrport.c::omrport_allocate_library "omrport_allocate_library()". * This function allocates, initializes and starts the port library. * The port library is responsible for deallocation of this memory * as part of it's shutdown. */ TEST(PortTest, port_test5) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrport_test5"; OMRPortLibrary *fakePortLibrary = NULL; int32_t rc; omrthread_t attachedThread = NULL; reportTestEntry(OMRPORTLIB, testName); if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "Failed to attach to omrthread\n"); goto exit; } /* Pass */ fakePortLibrary = NULL; rc = omrport_allocate_library(&fakePortLibrary); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned %d expected 0\n", rc); goto exit; } /* Verify we have a pointer */ if (NULL == fakePortLibrary) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned NULL pointer\n"); goto exit; } /* Verify not started */ if (NULL != fakePortLibrary->portGlobals) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() portGlobals pointer is not NULL\n"); } /* Verify self allocated */ if (NULL == fakePortLibrary->self_handle) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() self_handle pointer is NULL\n"); } /* Verify it will start */ rc = omrport_startup_library(fakePortLibrary); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected 0\n", rc); } /* Take this port library down */ fakePortLibrary->port_shutdown_library(fakePortLibrary); /* Try again, but force failure during startup by over riding one of the startup functions */ fakePortLibrary = NULL; rc = omrport_allocate_library(&fakePortLibrary); if (0 != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_allocate_library() returned %d expected 0\n", rc); goto exit; } /* Override omrmem_startup */ fakePortLibrary->mem_startup = fake_mem_startup; rc = omrport_startup_library(fakePortLibrary); if (failMemStartup != rc) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrport_startup_library() returned %d expected %d\n", rc, failMemStartup); } /* No way to tell if it freed the memory properly. The pointer we have to the port library is * not updated as part of omrport_startup_library(), so we are now pointing at dead memory. * * NULL our pointer to exit can clean-up if required */ fakePortLibrary = NULL; exit: if (NULL != fakePortLibrary) { fakePortLibrary->port_shutdown_library(fakePortLibrary); } if (NULL != attachedThread) { omrthread_detach(attachedThread); } reportTestExit(OMRPORTLIB, testName); }
/** * This is child thread's entry point. It uses waitForEvent() and sendEvent() to synchronize * its operations with the main thread. * @param arg The pointer to passed in parameter which is a type of SigMaskTestInfo. * @return 0 thread return normally. -1 thread return with error. */ static int sigMaskThread(void *arg) { SigMaskTestInfo *info = (SigMaskTestInfo *)arg; struct OMRPortLibrary *portLibrary = info->portLibrary; OMRPORT_ACCESS_FROM_OMRPORT(portLibrary); const char *testName = info->testName; uint32_t protectResult = 0; uintptr_t result = 1; uint32_t flags = 0; pthread_t thread = pthread_self(); sigset_t mask; /* initialize local variables */ sigemptyset(&mask); portTestEnv->log("%s\t:thread is ready for testing.\n", testName); sendEvent(info, READY, &thread, sizeof(thread)); /* pthread_sigmask */ if (!waitForEvent(testName, info, SIGMASK, &flags, sizeof(flags))) { return -1; } portTestEnv->log("%s\t:starting pthread_sigmask test...\n", testName); if (0 != pthread_sigmask(SIG_SETMASK, NULL, &mask)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno); return -1; } if (0 != flags) { sigaddset(&mask, flags); if (0 != pthread_sigmask(SIG_SETMASK, &mask, NULL)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno); return -1; } if (0 != pthread_sigmask(SIG_SETMASK, NULL, &mask)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno); return -1; } } portTestEnv->log("%s\t:pthread_sigmask test has been done. send result back to main thread.\n", testName); sendEvent(info, READY, &mask, sizeof(mask)); /* pthread_kill */ if (!waitForEvent(testName, info, PTHREADKILL, &flags, sizeof(flags))) { return -1; } portTestEnv->log("%s\t:starting signal handling test in protected function...\n", testName); if (!omrsig_can_protect(flags)) { operationNotSupported(OMRPORTLIB, "the specified signals are"); return -1; } else { protectResult = omrsig_protect( info->fn, (void *)info, sigHandlerFunction, (void *)info, flags, &result); if ((OMRPORT_SIG_EXCEPTION_OCCURRED == protectResult) && (0 != result)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "portLibrary->sig_protect -- expected 0 in *result\n"); } portTestEnv->log("%s\t:protected function finished.\n", testName); sendEvent(info, FINISHED, NULL, 0); } return 0; }
/* * Test pthread_sigmask() with cross fire signaling. * - create 2 threads * - one thread calls pthread_sigmask() and verifies that the specified mask is set * - other thread verifies that the specified mask is not set * - send some signals to each thread, e.g. by pthread_kill and verify that it is blocked or not. * * Note: under heavy load test environment, the signal may not be delivered in timely fashion * * mask thread:----s(READY)-w(SIGMASK)-----------m---s(READY)-w(PTHREADKILL)----------j----s(READY)------w(EXIT)-------s(FINISHED)---------->> * main thread:-w(READY)---------s(SIGMASK)-w(READY)------------c----s(PTHREADKILL)-w(READY)----------k----s(EXIT)--w(FINISHED)--------->> * * main thread:-w(READY)---------s(SIGMASK)-w(READY)------------c----s(PTHREADKILL)----w(FINISHED)---------->> * unmask thread:---s(READY)-w(SIGMASK)-------m--s(READY)-w(PTHREADKILL)----------j----i----s(FINISHED)-------------->> * * where: * m: run pthread_sigmask * c: check result of pthread_sigmask * j: run sigprotected function * k: run pthread_kill * i: signal handler (OMRPORT_SIG_EXCEPTION_RETURN) * */ TEST(PortSignalExtendedTests, sig_ext_test1) { OMRPORT_ACCESS_FROM_OMRPORT(portTestEnv->getPortLibrary()); const char *testName = "omrsig_ext_test1"; omrthread_monitor_t maskMonitor = NULL; omrthread_monitor_t unmaskMonitor = NULL; omrthread_t mainThread = NULL; omrthread_t maskThread = NULL; omrthread_t unmaskThread = NULL; pthread_t osMaskThread = 0; pthread_t osUnmaskThread = 0; uint32_t flags = 0; SigMaskTestInfo maskThreadInfo; SigMaskTestInfo unmaskThreadInfo; intptr_t monitorRC = 0; int memcmp_ret = 0; sigset_t mask; sigset_t oldMask; sigset_t currentMask; sigset_t maskThread_mask; sigset_t unmaskThread_mask; portTestEnv->changeIndent(1); reportTestEntry(OMRPORTLIB, testName); /* initialize local variables */ memset(&maskThreadInfo, 0, sizeof(maskThreadInfo)); memset(&unmaskThreadInfo, 0, sizeof(unmaskThreadInfo)); sigemptyset(&mask); sigemptyset(&oldMask); sigemptyset(¤tMask); sigemptyset(&maskThread_mask); sigemptyset(&unmaskThread_mask); /* * OSX will redirect the SIGILL from the masked thread to other threads unless they are also masked. * This thread's mask will be inherited. Mask SIGILL for all threads for mask testing. */ sigaddset(&mask, SIGILL); if (0 != pthread_sigmask(SIG_SETMASK, &mask, &oldMask)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno); FAIL(); } monitorRC = omrthread_monitor_init_with_name(&maskMonitor, 0, "omrsig_ext_sigmask_monitor"); if (0 != monitorRC) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrthread_monitor_init_with_name failed with %i\n", monitorRC); FAIL(); } setSigMaskTestInfo(&maskThreadInfo, OMRPORTLIB, "Masked Thread", maskMonitor, maskProtectedFunction, INVALID); monitorRC = omrthread_monitor_init_with_name(&unmaskMonitor, 0, "omrsig_ext_sigunmask_monitor"); if (0 != monitorRC) { outputErrorMessage(PORTTEST_ERROR_ARGS, "omrthread_monitor_init_with_name failed with %i\n", monitorRC); FAIL(); } setSigMaskTestInfo(&unmaskThreadInfo, OMRPORTLIB, "Unmasked Thread", unmaskMonitor, unmaskProtectedFunction, INVALID); mainThread = omrthread_self(); maskThread = create_thread(OMRPORTLIB, (omrthread_entrypoint_t)sigMaskThread, &maskThreadInfo); unmaskThread = create_thread(OMRPORTLIB, (omrthread_entrypoint_t)sigMaskThread, &unmaskThreadInfo); if ((NULL != mainThread) && (NULL != maskThread) && (NULL != unmaskThread)) { portTestEnv->log("%s\t:created test threads.\n", testName); /* wait for maskThread and unmaskThread ready */ if (!waitForEvent(testName, &maskThreadInfo, READY, &osMaskThread, sizeof(pthread_t))) { goto exit; } if (!waitForEvent(testName, &unmaskThreadInfo, READY, &osUnmaskThread, sizeof(pthread_t))) { goto exit; } portTestEnv->log("%s\t:test threads are READY.\n", testName); /* test pthread_sigmask */ /* ask maskThread to mask SIGBUS signal */ flags = SIGBUS; portTestEnv->log("%s\t:configure mask thread to mask SIGBUS signal.\n", testName); sendEvent(&maskThreadInfo, SIGMASK, &flags, sizeof(flags)); /* ask unMaskThread to not mask any signal */ flags = 0; portTestEnv->log("%s\t:configure unmask thread to not mask any tested signal.\n", testName); sendEvent(&unmaskThreadInfo, SIGMASK, &flags, sizeof(flags)); portTestEnv->log("%s\t:testing pthread_sigmask...\n", testName); /* check pthread_sigmask result */ if (!waitForEvent(testName, &maskThreadInfo, READY, &maskThread_mask, sizeof(maskThread_mask))) { goto exit; } if (!waitForEvent(testName, &unmaskThreadInfo, READY, &unmaskThread_mask, sizeof(unmaskThread_mask))) { goto exit; } portTestEnv->log("%s\t:operation pthread_sigmask has been done. checking pthread_sigmask result...\n", testName); /* * Expected behavior: * 1. main thread's signal mask shall be untouched * 2. child threads shall inherit main thread's signal mask * 3. child threads' pthread_sigmask operation shall not interfere each other */ if (0 != pthread_sigmask(SIG_SETMASK, NULL, ¤tMask)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask failed: %s(%d).\n", strerror(errno), errno); goto exit; } /* check whether main thread signal mask was affected by child thread pthread_sigmask operation */ if (0 != (memcmp_ret = memcmp(¤tMask, &mask, sizeof(currentMask)))) { outputErrorMessage(PORTTEST_ERROR_ARGS, "main thread mask was modified (old=0x%X, new=0x%X), %X\n", *((uint32_t *)&mask), *((uint32_t *)¤tMask), memcmp_ret); goto exit; } else { portTestEnv->log("%s\t:main thread signal mask was not affected.\n", testName); } /* UNIX opengroup example says that newly created thread shall inherit the mask */ if (!sigismember(&maskThread_mask, SIGILL) || !sigismember(&unmaskThread_mask, SIGILL)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "created threads did not inherit mask.(maskThreadInfo=0x%X, unmaskThreadInfo=0x%X)\n", *((uint32_t *)&maskThread_mask), *((uint32_t *)&unmaskThread_mask)); goto exit; } else { portTestEnv->log("%s\t:child thread inherited main thread's signal mask.\n", testName); } /* Check whether two child threads' pthread_sigmask operation can interfere each other. */ if (!sigismember(&maskThread_mask, SIGBUS) || sigismember(&unmaskThread_mask, SIGBUS)) { outputErrorMessage(PORTTEST_ERROR_ARGS, "pthread_sigmask did not work.(maskThreadInfo=0x%X, unmaskThreadInfo=0x%X)\n", *((uint32_t *)&maskThread_mask), *((uint32_t *)&unmaskThread_mask)); goto exit; } else { portTestEnv->log("%s\t:pthread_sigmask operation in each child thread did not interfere each other.\n", testName); } /* * test unmask thread signal handling behavior * unmask thread will install SIGSEGV handler and launch a protected function unmaskProtectedFunction(). * unmaskProtectedFunction() shall be terminated by SIGSEGV generated in its body, and the unmask thread * will send report to this main thread. */ flags = OMRPORT_SIG_FLAG_MAY_RETURN | OMRPORT_SIG_FLAG_SIGSEGV; /* SIGSEGV shall be received */ portTestEnv->log("%s\t:configure unmask thread to prepare for unmasked signal SIGSEGV test.\n", testName); sendEvent(&unmaskThreadInfo, PTHREADKILL, &flags, sizeof(flags)); if (!waitForEvent(testName, &unmaskThreadInfo, FINISHED, NULL, 0)) { goto exit; } else { portTestEnv->log("%s\t:unmasked thread finished. checking unmask thread's signal status...\n", testName); if (unmaskThreadInfo.bulletinBoard.status == SIGNALED) { portTestEnv->log("%s\t:unmasked thread received signal as expected.\n", testName); } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "unmasked thread did not received signal as expected.(SignalStatus=%d)\n", unmaskThreadInfo.bulletinBoard.status); goto exit; } } /* * test mask thread signal handling behavior * mask thread will install SIGILL handler and launch a protected function maskProtectedFunction(). */ portTestEnv->log("%s\t:testing pthread_kill...\n", testName); flags = OMRPORT_SIG_FLAG_MAY_RETURN | OMRPORT_SIG_FLAG_SIGILL; /* SIGILL shall not be received */ sendEvent(&maskThreadInfo, PTHREADKILL, &flags, sizeof(flags)); portTestEnv->log("%s\t:configure mask thread to prepare for pthread_kill test.\n", testName); if (!waitForEvent(testName, &maskThreadInfo, READY, NULL, 0)) { goto exit; } portTestEnv->log("%s\t:mask thread is ready to receive signal. sending pthread_kill...\n", testName); /* send SIGILL to maskThread which will never receive this signal */ pthread_kill(osMaskThread, SIGILL); /* check pthread_kill result */ /* * Expected behavior: * 1. child thread with signal mask on SIGILL shall not receive this signal and therefore NOTSIGNALED. */ portTestEnv->log("%s\t:notify mask thread to exit.\n", testName); sendEvent(&maskThreadInfo, EXIT, NULL, 0); if (!waitForEvent(testName, &maskThreadInfo, FINISHED, NULL, 0)) { goto exit; } else { portTestEnv->log("%s\t:masked thread finished. checking mask thread's signal status...\n", testName); if (maskThreadInfo.bulletinBoard.status == NOTSIGNALED) { portTestEnv->log("%s\t:masked thread did not receive signal as expected.\n", testName); } else { outputErrorMessage(PORTTEST_ERROR_ARGS, "masked thread received signal as not expected.(SignalStatus=%d)\n", maskThreadInfo.bulletinBoard.status); goto exit; } } portTestEnv->log("%s\t:pthread_sigmask works on each individual thread.\n", testName); } portTestEnv->log("%s\t:destroying unmaskMonitor...\n", testName); omrthread_monitor_destroy(unmaskMonitor); portTestEnv->log("%s\t:destroying maskMonitor...\n", testName); omrthread_monitor_destroy(maskMonitor); goto cleanup; exit: portTestEnv->log(LEVEL_ERROR, "%s\t:test stopped with errors\n", testName); FAIL(); cleanup: /* restore signal mask */ pthread_sigmask(SIG_SETMASK, &oldMask, NULL); portTestEnv->changeIndent(-1); reportTestExit(OMRPORTLIB, testName); }