diff options
author | Jonathon Reinhart <Jonathon.Reinhart@gmail.com> | 2015-09-07 23:26:20 -0400 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2015-09-14 18:17:10 +0200 |
commit | fd4b80d4504563f8b4d4f518b3122d17a669d1ed (patch) | |
tree | b332fabd1f8010d3c737444e6ba84dbf41d375c7 | |
parent | 5d4229c8381fbbc09dd733ac9448a5d79fb98840 (diff) | |
download | cmocka-fd4b80d4504563f8b4d4f518b3122d17a669d1ed.tar.gz cmocka-fd4b80d4504563f8b4d4f518b3122d17a669d1ed.tar.bz2 cmocka-fd4b80d4504563f8b4d4f518b3122d17a669d1ed.zip |
Use sigsetjmp()/siglongjmp() when available
Without using siglongjmp, the signal mask is not restored when
longjmp-ing from the signal handler, and whichever signal was
being handled remains blocked for the remainder of the tests. As a
result, the same signal cannot be caught twice, and will cause process
termination when being raised the second time.
This does not change 'jmp_buf global_expect_assert_env', because it is
part of the public API, and isn't used from a signal handler.
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
-rw-r--r-- | ConfigureChecks.cmake | 1 | ||||
-rw-r--r-- | config.h.cmake | 3 | ||||
-rw-r--r-- | src/cmocka.c | 22 |
3 files changed, 22 insertions, 4 deletions
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index c0dd13d..c82f099 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -76,6 +76,7 @@ check_function_exists(exit HAVE_EXIT) check_function_exists(fprintf HAVE_FPRINTF) check_function_exists(free HAVE_FREE) check_function_exists(longjmp HAVE_LONGJMP) +check_function_exists(siglongjmp HAVE_SIGLONGJMP) check_function_exists(malloc HAVE_MALLOC) check_function_exists(memcpy HAVE_MEMCPY) check_function_exists(memset HAVE_MEMSET) diff --git a/config.h.cmake b/config.h.cmake index 78cce7a..920bb10 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -110,6 +110,9 @@ /* Define to 1 if you have the `longjmp' function. */ #cmakedefine HAVE_LONGJMP 1 +/* Define to 1 if you have the `siglongjmp' function. */ +#cmakedefine HAVE_SIGLONGJMP 1 + /* Define to 1 if you have the `malloc' function. */ #cmakedefine HAVE_MALLOC 1 diff --git a/src/cmocka.c b/src/cmocka.c index 284d55f..fda3682 100644 --- a/src/cmocka.c +++ b/src/cmocka.c @@ -84,6 +84,20 @@ #define CMOCKA_CLOCK_GETTIME(clock_id, ts) #endif +/** + * POSIX has sigsetjmp/siglongjmp, while Windows only has setjmp/longjmp. + */ +#ifdef HAVE_SIGLONGJMP +# define cm_jmp_buf sigjmp_buf +# define cm_setjmp(env) sigsetjmp(env, 1) +# define cm_longjmp(env, val) siglongjmp(env, val) +#else +# define cm_jmp_buf jmp_buf +# define cm_setjmp(env) setjmp(env) +# define cm_longjmp(env, val) longjmp(env, val) +#endif + + /* * Declare and initialize the pointer member of ValuePointer variable name * with ptr. @@ -238,7 +252,7 @@ void cm_print_error(const char * const format, ...) CMOCKA_PRINTF_ATTRIBUTE(1, 2 * Keeps track of the calling context returned by setenv() so that the fail() * method can jump out of a test. */ -static CMOCKA_THREAD jmp_buf global_run_test_env; +static CMOCKA_THREAD cm_jmp_buf global_run_test_env; static CMOCKA_THREAD int global_running_test = 0; /* Keeps track of the calling context returned by setenv() so that */ @@ -347,7 +361,7 @@ static void exit_test(const int quit_application) print_error("%s", cm_error_message); abort(); } else if (global_running_test) { - longjmp(global_run_test_env, 1); + cm_longjmp(global_run_test_env, 1); } else if (quit_application) { exit(-1); } @@ -2339,7 +2353,7 @@ static int cmocka_run_one_test_or_fixture(const char *function_name, global_running_test = 1; - if (setjmp(global_run_test_env) == 0) { + if (cm_setjmp(global_run_test_env) == 0) { if (test_func != NULL) { test_func(state != NULL ? state : ¤t_state); @@ -2677,7 +2691,7 @@ int _run_test( } initialize_testing(function_name); global_running_test = 1; - if (setjmp(global_run_test_env) == 0) { + if (cm_setjmp(global_run_test_env) == 0) { Function(state ? state : ¤t_state); fail_if_leftover_values(function_name); |