/* * Copyright (c) 2018-2020, Andreas Kling * Copyright (c) 2019-2020, Shannon Booth * Copyright (c) 2021, Brian Gianforcaro * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #ifndef AK_OS_MACOS # include #endif namespace Test { Crash::Crash(String test_type, Function crash_function) : m_type(move(test_type)) , m_crash_function(move(crash_function)) { } bool Crash::run(RunType run_type) { outln("\x1B[33mTesting\x1B[0m: \"{}\"", m_type); if (run_type == RunType::UsingCurrentProcess) { return do_report(m_crash_function()); } else { // Run the test in a child process so that we do not crash the crash program :^) pid_t pid = fork(); if (pid < 0) { perror("fork"); VERIFY_NOT_REACHED(); } else if (pid == 0) { #ifndef AK_OS_MACOS if (prctl(PR_SET_DUMPABLE, 0, 0) < 0) perror("prctl(PR_SET_DUMPABLE)"); #endif exit((int)m_crash_function()); } int status; waitpid(pid, &status, 0); if (WIFEXITED(status)) { return do_report(Failure(WEXITSTATUS(status))); } if (WIFSIGNALED(status)) { outln("\x1B[32mPASS\x1B[0m: Terminated with signal {}", WTERMSIG(status)); return true; } VERIFY_NOT_REACHED(); } } bool Crash::do_report(Failure failure) { // If we got here something went wrong out("\x1B[31mFAIL\x1B[0m: "); switch (failure) { case Failure::DidNotCrash: outln("Did not crash!"); break; case Failure::UnexpectedError: outln("Unexpected error!"); break; default: VERIFY_NOT_REACHED(); } return false; } }