From 0e7fcaa166d1839a578ce845ec1c9be17715083f Mon Sep 17 00:00:00 2001 From: Nicolas Bourdaud Date: Fri, 6 Jan 2023 09:15:25 +0100 Subject: [PATCH] tests: add wait_signal test in process-api-tests.c Test for reported signal in status by mm_wait_process() in case of the process is killed. Change-Id: I565d5bd4df2ade370077f5027dab885f1d2ba54f --- tests/child-proc.c | 42 +++++++++++++++++++++++++++++++++++++++ tests/process-api-tests.c | 33 ++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/tests/child-proc.c b/tests/child-proc.c index 097f266..a892e8c 100644 --- a/tests/child-proc.c +++ b/tests/child-proc.c @@ -6,10 +6,32 @@ #endif #include +#include #include #include #include +#ifdef _WIN32 +#include +#endif + +#if defined(_MSC_VER) +# define raise_sigill __ud2 +#else +# define raise_sigill __builtin_trap +#endif + + +static +void raise_sigfpe(void) +{ +#ifdef _WIN32 + RaiseException(EXCEPTION_FLT_DIVIDE_BY_ZERO, 0, 0, NULL); +#else + raise(SIGFPE); +#endif +} + static int check_open_files(int argc, char* argv[]) @@ -33,6 +55,23 @@ int check_open_files(int argc, char* argv[]) } +static +int check_signal(int signum) +{ + union {int* iptr; intptr_t v;} val = {.v = 0}; + + switch (signum) { + case SIGABRT: abort(); + case SIGSEGV: printf("%i", *val.iptr); break; // Must raise segfault + case SIGFPE: raise_sigfpe(); break; + case SIGILL: raise_sigill(); break; + default: raise(signum); + } + + return EXIT_FAILURE; +} + + int main(int argc, char* argv[]) { if (argc < 2) { @@ -46,6 +85,9 @@ int main(int argc, char* argv[]) if (strcmp(argv[1], "check-exit") == 0) return atoi(argv[2]); + if (strcmp(argv[1], "check-signal") == 0) + return check_signal(atoi(argv[2])); + fprintf(stderr, "child-proc: invalid argument: %s\n", argv[1]); return EXIT_FAILURE; } diff --git a/tests/process-api-tests.c b/tests/process-api-tests.c index 9c3c807..a933e62 100644 --- a/tests/process-api-tests.c +++ b/tests/process-api-tests.c @@ -7,6 +7,7 @@ #include +#include #include #include @@ -520,6 +521,37 @@ START_TEST(wait_exit) END_TEST +static const int wait_signal_cases[] = { + SIGSEGV, + SIGILL, + SIGFPE, +#if !defined(_WIN32) + SIGTERM, + SIGABRT, + SIGINT, +#endif +}; + +START_TEST(wait_signal) +{ + int status; + mm_pid_t pid; + char arg[32]; + int signum = wait_signal_cases[_i]; + char* cmd[] = {CHILDPROC_BINPATH, "check-signal", arg, NULL}; + + sprintf(arg, "%i", signum); + + ck_assert(mm_spawn(&pid, cmd[0], 0, NULL, 0, cmd, NULL) == 0); + ck_assert(mm_wait_process(pid, &status) == 0); + + // Check process is exited and exit code is the one expected + ck_assert(status & MM_WSTATUS_SIGNALED); + ck_assert_int_eq(status & MM_WSTATUS_CODEMASK, signum); +} +END_TEST + + /************************************************************************** * * * process test suite setup * @@ -542,6 +574,7 @@ TCase* create_process_tcase(void) tcase_add_loop_test(tc, spawn_invalid_args, 0, MM_NELEM(inval_cases)); tcase_add_test(tc, wait_twice); tcase_add_loop_test(tc, wait_exit, 0, MM_NELEM(exit_code_cases)); + tcase_add_loop_test(tc, wait_signal, 0, MM_NELEM(wait_signal_cases)); #ifndef _WIN32 tcase_add_loop_test(tc, spawn_error_limits, 0, NUM_ERRLIMITS_CASES);