summaryrefslogtreecommitdiff
path: root/src/pal/tests/palsuite/exception_handling/pal_sxs
diff options
context:
space:
mode:
Diffstat (limited to 'src/pal/tests/palsuite/exception_handling/pal_sxs')
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt97
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp75
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.src3
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp75
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.src3
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/exceptionsxs.cpp117
-rw-r--r--src/pal/tests/palsuite/exception_handling/pal_sxs/test1/testinfo.dat13
8 files changed, 387 insertions, 0 deletions
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_sxs/CMakeLists.txt
new file mode 100644
index 0000000000..f6aa0cb2d9
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/CMakeLists.txt
@@ -0,0 +1,4 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+add_subdirectory(test1)
+
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt
new file mode 100644
index 0000000000..b0458db998
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/CMakeLists.txt
@@ -0,0 +1,97 @@
+cmake_minimum_required(VERSION 2.8.12.2)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+if(CLR_CMAKE_PLATFORM_UNIX)
+ add_compile_options(-fPIC)
+ add_definitions(-DFEATURE_ENABLE_HARDWARE_EXCEPTIONS)
+endif(CLR_CMAKE_PLATFORM_UNIX)
+
+# Set the RPATH of paltest_pal_sxs_test1 so that it can find dependencies without needing to set LD_LIBRARY
+# For more information: http://www.cmake.org/Wiki/CMake_RPATH_handling.
+if(CORECLR_SET_RPATH)
+ if(CLR_CMAKE_PLATFORM_LINUX)
+ set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
+ set(CMAKE_INSTALL_RPATH "\$ORIGIN")
+ endif(CLR_CMAKE_PLATFORM_LINUX)
+endif(CORECLR_SET_RPATH)
+
+# Test DLL1
+
+set(DEF_SOURCES1 dlltest1.src)
+convert_to_absolute_path(DEF_SOURCES1 ${DEF_SOURCES1})
+set(EXPORTS_FILE1 ${CMAKE_CURRENT_BINARY_DIR}/dlltest1.exports)
+generate_exports_file(${DEF_SOURCES1} ${EXPORTS_FILE1})
+
+if(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ set(EXPORTS_LINKER_OPTION1 -Wl,--version-script=${EXPORTS_FILE1})
+endif(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(EXPORTS_LINKER_OPTION1 -Wl,-exported_symbols_list,${EXPORTS_FILE1})
+endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+set(DLL1SOURCES dlltest1.cpp)
+add_library(paltest_pal_sxs_test1_dll1 SHARED ${DLL1SOURCES})
+add_custom_target(dlltest1_exports DEPENDS ${EXPORTS_FILE1})
+set_property(TARGET paltest_pal_sxs_test1_dll1 APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION1})
+set_property(TARGET paltest_pal_sxs_test1_dll1 APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE1})
+
+add_dependencies(paltest_pal_sxs_test1_dll1
+ dlltest1_exports
+ coreclrpal
+)
+
+target_link_libraries(paltest_pal_sxs_test1_dll1
+ pthread
+ m
+ coreclrpal
+)
+
+# Test DLL2
+
+set(DEF_SOURCES2 dlltest2.src)
+convert_to_absolute_path(DEF_SOURCES2 ${DEF_SOURCES2})
+set(EXPORTS_FILE2 ${CMAKE_CURRENT_BINARY_DIR}/dlltest2.exports)
+generate_exports_file(${DEF_SOURCES2} ${EXPORTS_FILE2})
+
+if(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+ set(EXPORTS_LINKER_OPTION2 -Wl,--version-script=${EXPORTS_FILE2})
+endif(CMAKE_SYSTEM_NAME STREQUAL Linux OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD OR CMAKE_SYSTEM_NAME STREQUAL NetBSD)
+
+if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+ set(EXPORTS_LINKER_OPTION2 -Wl,-exported_symbols_list,${EXPORTS_FILE2})
+endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
+
+set(DLL2SOURCES dlltest2.cpp)
+add_library(paltest_pal_sxs_test1_dll2 SHARED ${DLL2SOURCES})
+add_custom_target(dlltest2_exports DEPENDS ${EXPORTS_FILE2})
+set_property(TARGET paltest_pal_sxs_test1_dll2 APPEND_STRING PROPERTY LINK_FLAGS ${EXPORTS_LINKER_OPTION2})
+set_property(TARGET paltest_pal_sxs_test1_dll2 APPEND_STRING PROPERTY LINK_DEPENDS ${EXPORTS_FILE2})
+
+add_dependencies(paltest_pal_sxs_test1_dll2
+ dlltest2_exports
+ coreclrpal
+)
+
+target_link_libraries(paltest_pal_sxs_test1_dll2
+ pthread
+ m
+ coreclrpal
+)
+
+# Main program
+
+set(TESTSOURCES exceptionsxs.cpp)
+
+add_executable(paltest_pal_sxs_test1 ${TESTSOURCES})
+
+add_dependencies(paltest_pal_sxs_test1
+ paltest_pal_sxs_test1_dll1
+ paltest_pal_sxs_test1_dll2
+)
+
+target_link_libraries(paltest_pal_sxs_test1
+ paltest_pal_sxs_test1_dll1
+ paltest_pal_sxs_test1_dll2
+)
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp
new file mode 100644
index 0000000000..614690897a
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.cpp
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: dlltest1.c (exception_handling\pal_sxs\test1)
+**
+** Purpose: Test to make sure the PAL_EXCEPT block is executed
+** after an exception occurs in the PAL_TRY block with
+** multiple PALs in the process.
+**
+**
+**===================================================================*/
+#include <palsuite.h>
+
+extern "C"
+int InitializeDllTest1()
+{
+ return PAL_InitializeDLL();
+}
+
+BOOL bTry = FALSE;
+BOOL bExcept = FALSE;
+
+extern "C"
+int DllTest1()
+{
+ Trace("Starting pal_sxs test1 DllTest1\n");
+
+ PAL_TRY(VOID*, unused, NULL)
+ {
+ volatile int* p = (volatile int *)0x11; // Invalid pointer
+
+ bTry = TRUE; // Indicate we hit the PAL_TRY block
+ *p = 1; // Causes an access violation exception
+
+ Fail("ERROR: code was executed after the access violation.\n");
+ }
+ PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ if (!bTry)
+ {
+ Fail("ERROR: PAL_EXCEPT was hit without PAL_TRY being hit.\n");
+ }
+
+ // Validate that the faulting address is correct; the contents of "p" (0x11).
+ if (ex.GetExceptionRecord()->ExceptionInformation[1] != 0x11)
+ {
+ Fail("ERROR: PAL_EXCEPT ExceptionInformation[1] != 0x11\n");
+ }
+
+ bExcept = TRUE; // Indicate we hit the PAL_EXCEPT block
+ }
+ PAL_ENDTRY;
+
+ if (!bTry)
+ {
+ Trace("ERROR: the code in the PAL_TRY block was not executed.\n");
+ }
+
+ if (!bExcept)
+ {
+ Trace("ERROR: the code in the PAL_EXCEPT block was not executed.\n");
+ }
+
+ // Did we hit all the code blocks?
+ if(!bTry || !bExcept)
+ {
+ Fail("DllTest1 FAILED\n");
+ }
+
+ Trace("DLLTest1 PASSED\n");
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.src b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.src
new file mode 100644
index 0000000000..0a0a6ee44a
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest1.src
@@ -0,0 +1,3 @@
+InitializeDllTest1
+DllTest1
+
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp
new file mode 100644
index 0000000000..1e85821422
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.cpp
@@ -0,0 +1,75 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: dlltest2.c (exception_handling\pal_sxs\test1)
+**
+** Purpose: Test to make sure the PAL_EXCEPT block is executed
+** after an exception occurs in the PAL_TRY block with
+** multiple PALs in the process.
+**
+**
+**===================================================================*/
+#include <palsuite.h>
+
+extern "C"
+int InitializeDllTest2()
+{
+ return PAL_InitializeDLL();
+}
+
+BOOL bTry = FALSE;
+BOOL bExcept = FALSE;
+
+extern "C"
+int DllTest2()
+{
+ Trace("Starting pal_sxs test1 DllTest2\n");
+
+ PAL_TRY(VOID*, unused, NULL)
+ {
+ volatile int* p = (volatile int *)0x22; // Invalid pointer
+
+ bTry = TRUE; // Indicate we hit the PAL_TRY block
+ *p = 2; // Causes an access violation exception
+
+ Fail("ERROR: code was executed after the access violation.\n");
+ }
+ PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ if (!bTry)
+ {
+ Fail("ERROR: PAL_EXCEPT was hit without PAL_TRY being hit.\n");
+ }
+
+ // Validate that the faulting address is correct; the contents of "p" (0x22).
+ if (ex.GetExceptionRecord()->ExceptionInformation[1] != 0x22)
+ {
+ Fail("ERROR: PAL_EXCEPT ExceptionInformation[1] != 0x22\n");
+ }
+
+ bExcept = TRUE; // Indicate we hit the PAL_EXCEPT block
+ }
+ PAL_ENDTRY;
+
+ if (!bTry)
+ {
+ Trace("ERROR: the code in the PAL_TRY block was not executed.\n");
+ }
+
+ if (!bExcept)
+ {
+ Trace("ERROR: the code in the PAL_EXCEPT block was not executed.\n");
+ }
+
+ // Did we hit all the code blocks?
+ if(!bTry || !bExcept)
+ {
+ Fail("DllTest2 FAILED\n");
+ }
+
+ Trace("DLLTest2 PASSED\n");
+ return PASS;
+}
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.src b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.src
new file mode 100644
index 0000000000..433419bc5b
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/dlltest2.src
@@ -0,0 +1,3 @@
+InitializeDllTest2
+DllTest2
+
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/exceptionsxs.cpp b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/exceptionsxs.cpp
new file mode 100644
index 0000000000..97a963c120
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/exceptionsxs.cpp
@@ -0,0 +1,117 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*=====================================================================
+**
+** Source: exceptionsxs.c (exception_handling\pal_sxs\test1)
+**
+** Purpose: Test to make sure the PAL_EXCEPT block is executed
+** after an exception occurs in the PAL_TRY block with
+** multiple PALs in the process.
+**
+**
+**===================================================================*/
+
+#include <stdio.h>
+#include <signal.h>
+#include <errno.h>
+#include <sys/ucontext.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
+enum
+{
+ PASS = 0,
+ FAIL = 1
+};
+
+extern "C" int InitializeDllTest1();
+extern "C" int InitializeDllTest2();
+extern "C" int DllTest1();
+extern "C" int DllTest2();
+
+bool bSignal = false;
+bool bCatch = false;
+bool bHandler = false;
+
+void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
+{
+ printf("pal_sxs test1: signal handler called\n");
+ bHandler = true; // Mark that the signal handler was executed
+
+ if (!bSignal)
+ {
+ printf("ERROR: executed signal handler NOT from try/catch\n");
+ _exit(FAIL);
+ }
+
+ // Validate that the faulting address is correct; the contents of "p" (0x22).
+ if (siginfo->si_addr != (void *)0x33)
+ {
+ printf("ERROR: signal handler faulting address != 0x33\n");
+ _exit(FAIL);
+ }
+
+ // Unmask signal so we can receive it again
+ sigset_t signal_set;
+ sigemptyset(&signal_set);
+ sigaddset(&signal_set, SIGSEGV);
+ if (-1 == sigprocmask(SIG_UNBLOCK, &signal_set, NULL))
+ {
+ printf("ERROR: sigprocmask failed; error is %d\n", errno);
+ _exit(FAIL);
+ }
+
+ printf("Signal chaining PASSED\n");
+ _exit(PASS);
+}
+
+int main(int argc, char *argv[])
+{
+ struct sigaction newAction;
+ struct sigaction oldAction;
+ newAction.sa_flags = SA_SIGINFO | SA_RESTART;
+ newAction.sa_handler = NULL;
+ newAction.sa_sigaction = sigsegv_handler;
+ sigemptyset(&newAction.sa_mask);
+
+ if (-1 == sigaction(SIGSEGV, &newAction, &oldAction))
+ {
+ printf("ERROR: sigaction failed; error is %d\n", errno);
+ return FAIL;
+ }
+
+ printf("PAL_SXS test1 SIGSEGV handler %p\n", oldAction.sa_sigaction);
+
+ if (0 != InitializeDllTest1())
+ {
+ return FAIL;
+ }
+
+ if (0 != InitializeDllTest2())
+ {
+ return FAIL;
+ }
+
+ // Test catching exceptions in other PAL instances
+ DllTest2();
+ DllTest1();
+ DllTest2();
+
+ if (bHandler)
+ {
+ printf("ERROR: signal handler called by PAL sxs tests\n");
+ return FAIL;
+ }
+
+ printf("Starting PAL_SXS test1 signal chaining\n");
+
+ bSignal = true;
+
+ volatile int* p = (volatile int *)0x33; // Invalid pointer
+ *p = 3; // Causes an access violation exception
+
+ printf("ERROR: code was executed after the access violation.\n");
+ return FAIL;
+}
diff --git a/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/testinfo.dat b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/testinfo.dat
new file mode 100644
index 0000000000..c0cf1ddfcb
--- /dev/null
+++ b/src/pal/tests/palsuite/exception_handling/pal_sxs/test1/testinfo.dat
@@ -0,0 +1,13 @@
+# Licensed to the .NET Foundation under one or more agreements.
+# The .NET Foundation licenses this file to you under the MIT license.
+# See the LICENSE file in the project root for more information.
+
+Version = 1.0
+Section = exception_handling
+Function = test1
+Name = pal_sxs test #1
+TYPE = DEFAULT
+EXE1 = test1
+LANG = cpp
+Description
+=Tests that exceptions across multiples pals work correctly