test_helpers.h 1.23 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
#ifndef PLS_TEST_TEST_HELPERS_H_
#define PLS_TEST_TEST_HELPERS_H_

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include <cstdlib>
#include <csignal>

// Source: https://stackoverflow.com/questions/15749071/fork-and-wait-in-c
// Works well enough for our purpose.
void abort_handler(int) {
  std::exit(1);
}

template<class F>
bool CHECK_ABORT(F &&f) {
  //spawn a new process
  auto child_pid = fork();

  //if the fork succeed
  if (child_pid >= 0) {

    //if we are in the child process
    if (child_pid == 0) {
      // Re-direct the signal handlers added by catch to simply exit with an error code
      std::signal(SIGABRT, abort_handler);
      std::signal(SIGFPE, abort_handler);
      std::signal(SIGSEGV, abort_handler);
      std::signal(SIGILL, abort_handler);

      //call the lambda that we expect to abort
      f();

      //if the function didn't abort, we'll exit cleanly
      std::exit(EXIT_SUCCESS);
    }
  }

  //determine if the child process aborted
  int exit_status;
  wait(&exit_status);

  //we check the exit status instead of a signal interrupt, because
  //Catch is going to catch the signal and exit with an error
  bool aborted = exit_status != 0;

  return aborted;
}

#endif //PLS_TEST_TEST_HELPERS_H_