From 2056698d6e5c0f6c7e3ab820e629ac0bbf1d31a9 Mon Sep 17 00:00:00 2001 From: otavepto <153766569+otavepto@users.noreply.github.com> Date: Sun, 7 Jan 2024 15:32:56 +0200 Subject: [PATCH] tests for crash printer --- crash_printer/tests/run_tests_linux.sh | 33 ++++++++++ crash_printer/tests/run_tests_win.bat | 47 +++++++++++++++ crash_printer/tests/test_helper.hpp | 35 +++++++++++ crash_printer/tests/test_linux_sa_handler.cpp | 60 +++++++++++++++++++ .../tests/test_linux_sa_sigaction.cpp | 60 +++++++++++++++++++ crash_printer/tests/test_win.cpp | 53 ++++++++++++++++ 6 files changed, 288 insertions(+) create mode 100644 crash_printer/tests/run_tests_linux.sh create mode 100644 crash_printer/tests/run_tests_win.bat create mode 100644 crash_printer/tests/test_helper.hpp create mode 100644 crash_printer/tests/test_linux_sa_handler.cpp create mode 100644 crash_printer/tests/test_linux_sa_sigaction.cpp create mode 100644 crash_printer/tests/test_win.cpp diff --git a/crash_printer/tests/run_tests_linux.sh b/crash_printer/tests/run_tests_linux.sh new file mode 100644 index 00000000..6a83e160 --- /dev/null +++ b/crash_printer/tests/run_tests_linux.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +my_dir="$(cd "$(dirname "$0")" && pwd)" + +pushd "$my_dir" > /dev/null + +clang++ -x c++ -rdynamic -std=c++17 -fvisibility=hidden -fexceptions -fno-jump-tables -Og -g3 -fPIE -I../ ../linux.cpp ../common.cpp test_linux_sa_handler.cpp -otest_linux_sa_handler && { + ./test_linux_sa_handler ; + echo "exit code = $?" ; + rm -f ./test_linux_sa_handler ; +} + +clang++ -x c++ -rdynamic -std=c++17 -fvisibility=hidden -fexceptions -fno-jump-tables -Og -g3 -fPIE -I../ ../linux.cpp ../common.cpp test_linux_sa_sigaction.cpp -otest_linux_sa_sigaction && { + ./test_linux_sa_sigaction ; + echo "exit code = $?" ; + rm -f ./test_linux_sa_sigaction ; +} + +clang++ -m32 -x c++ -rdynamic -std=c++17 -fvisibility=hidden -fexceptions -fno-jump-tables -Og -g3 -fPIE -I../ ../linux.cpp ../common.cpp test_linux_sa_handler.cpp -otest_linux_sa_handler && { + ./test_linux_sa_handler ; + echo "exit code = $?" ; + rm -f ./test_linux_sa_handler ; +} + +clang++ -m32 -x c++ -rdynamic -std=c++17 -fvisibility=hidden -fexceptions -fno-jump-tables -Og -g3 -fPIE -I../ ../linux.cpp ../common.cpp test_linux_sa_sigaction.cpp -otest_linux_sa_sigaction && { + ./test_linux_sa_sigaction ; + echo "exit code = $?" ; + rm -f ./test_linux_sa_sigaction ; +} + +rm -f -r ./crash_test + +popd > /dev/null diff --git a/crash_printer/tests/run_tests_win.bat b/crash_printer/tests/run_tests_win.bat new file mode 100644 index 00000000..1dec4398 --- /dev/null +++ b/crash_printer/tests/run_tests_win.bat @@ -0,0 +1,47 @@ +@echo off + +pushd "%~dp0" + +call :cleanup + +setlocal +call ..\..\build_win_set_env.bat 64 +cl.exe /DEBUG:FULL /Z7 /Od /std:c++17 /DYNAMICBASE /errorReport:none /nologo /utf-8 /EHsc /GF /GL- /GS /MT /I../ ../win.cpp ../common.cpp test_win.cpp kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Iphlpapi.lib Wldap32.lib Winmm.lib Bcrypt.lib Dbghelp.lib /link /DYNAMICBASE /ERRORREPORT:NONE /NOLOGO /OUT:test_win.exe && ( + call test_win.exe + + setlocal enableDelayedExpansion + echo exit code = !errorlevel! + endlocal + + call :cleanup +) +endlocal + +setlocal +call ..\..\build_win_set_env.bat 32 +cl.exe /DEBUG:FULL /Z7 /Od /std:c++17 /DYNAMICBASE /errorReport:none /nologo /utf-8 /EHsc /GF /GL- /GS /MT /I../ ../win.cpp ../common.cpp test_win.cpp kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib Iphlpapi.lib Wldap32.lib Winmm.lib Bcrypt.lib Dbghelp.lib /link /DYNAMICBASE /ERRORREPORT:NONE /NOLOGO /OUT:test_win.exe && ( + call test_win.exe + + setlocal enableDelayedExpansion + echo exit code = !errorlevel! + endlocal + + call :cleanup +) +endlocal + +rmdir /s /q crash_test + +popd + +exit /b 0 + + +:cleanup + del /f /q test_win.exe >nul 2>&1 + del /f /q test_win.ilk >nul 2>&1 + del /f /q test_win.obj >nul 2>&1 + del /f /q test_win.pdb >nul 2>&1 + del /f /q win.obj >nul 2>&1 + del /f /q common.obj >nul 2>&1 +exit /b diff --git a/crash_printer/tests/test_helper.hpp b/crash_printer/tests/test_helper.hpp new file mode 100644 index 00000000..c17eac49 --- /dev/null +++ b/crash_printer/tests/test_helper.hpp @@ -0,0 +1,35 @@ +#ifndef _TEST_CRASH_PRINTER_HELPER_H +#define _TEST_CRASH_PRINTER_HELPER_H + + +#include +#include + +static inline bool remove_file(const std::string &file) +{ + if (!std::filesystem::exists(file)) { + return true; + } + + if (std::filesystem::is_directory(file)) { + return false; + } + + return std::filesystem::remove(file); +} + +static inline bool remove_file(const std::wstring &file) +{ + if (!std::filesystem::exists(file)) { + return true; + } + + if (std::filesystem::is_directory(file)) { + return false; + } + + return std::filesystem::remove(file); +} + + +#endif // _TEST_CRASH_PRINTER_HELPER_H \ No newline at end of file diff --git a/crash_printer/tests/test_linux_sa_handler.cpp b/crash_printer/tests/test_linux_sa_handler.cpp new file mode 100644 index 00000000..1f90b9c9 --- /dev/null +++ b/crash_printer/tests/test_linux_sa_handler.cpp @@ -0,0 +1,60 @@ + +#include "crash_printer/linux.hpp" +#include "./test_helper.hpp" + + +#include +#include + +#include +#include // SIGBUS + SA_SIGINFO ... +#include // strsignal +#include // backtrace + backtrace_symbols + +std::string logs_filepath = "./crash_test/asd.txt"; + +// sa_sigaction handler for illegal instruction (SIGILL) +void exception_handler_SIGILL(int signal) +{ + std::ifstream file(logs_filepath); + if (file.is_open()) { + std::string line{}; + std::getline(file, line); + file.close(); + + if (line.size()) { + std::cout << "Success!" << std::endl; + exit(0); + } + } + + std::cerr << "Failed!" << std::endl; + exit(1); +} + + +int main() +{ + // simululate the existence of previous handler + struct sigaction sa_SIGSEGV_prev{}; + sa_SIGSEGV_prev.sa_handler = exception_handler_SIGILL; + sa_SIGSEGV_prev.sa_flags = SA_RESETHAND; + sigemptyset(&sa_SIGSEGV_prev.sa_mask); // all signals unblocked + sigaction(SIGSEGV, &sa_SIGSEGV_prev, nullptr); + + if (!remove_file(logs_filepath)) { + std::cerr << "failed to remove log" << std::endl; + return 1; + } + + if (!crash_printer::init(logs_filepath)) { + std::cerr << "failed to init" << std::endl; + return 1; + } + + // simulate a crash + volatile int * volatile ptr = nullptr; + *ptr = 42; + + return 0; +} diff --git a/crash_printer/tests/test_linux_sa_sigaction.cpp b/crash_printer/tests/test_linux_sa_sigaction.cpp new file mode 100644 index 00000000..06ccfba8 --- /dev/null +++ b/crash_printer/tests/test_linux_sa_sigaction.cpp @@ -0,0 +1,60 @@ + +#include "crash_printer/linux.hpp" +#include "./test_helper.hpp" + + +#include +#include + +#include +#include // SIGBUS + SA_SIGINFO ... +#include // strsignal +#include // backtrace + backtrace_symbols + +std::string logs_filepath = "./crash_test/asd.txt"; + +// sa_handler handler for illegal instruction (SIGILL) +void exception_handler_SIGILL(int signal, siginfo_t *info, void *context) +{ + std::ifstream file(logs_filepath); + if (file.is_open()) { + std::string line{}; + std::getline(file, line); + file.close(); + + if (line.size()) { + std::cout << "Success!" << std::endl; + exit(0); + } + } + + std::cerr << "Failed!" << std::endl; + exit(1); +} + + +int main() +{ + // simululate the existence of previous handler + struct sigaction sa_SIGSEGV_prev{}; + sa_SIGSEGV_prev.sa_sigaction = exception_handler_SIGILL; + sa_SIGSEGV_prev.sa_flags = SA_SIGINFO | SA_RESETHAND; + sigemptyset(&sa_SIGSEGV_prev.sa_mask); // all signals unblocked + sigaction(SIGSEGV, &sa_SIGSEGV_prev, nullptr); + + if (!remove_file(logs_filepath)) { + std::cerr << "failed to remove log" << std::endl; + return 1; + } + + if (!crash_printer::init(logs_filepath)) { + std::cerr << "failed to init" << std::endl; + return 1; + } + + // simulate a crash + volatile int * volatile ptr = nullptr; + *ptr = 42; + + return 0; +} diff --git a/crash_printer/tests/test_win.cpp b/crash_printer/tests/test_win.cpp new file mode 100644 index 00000000..2bcd0598 --- /dev/null +++ b/crash_printer/tests/test_win.cpp @@ -0,0 +1,53 @@ + +#include "crash_printer/win.hpp" +#include "./test_helper.hpp" + +#include +#include + +#define WIN32_LEAN_AND_MEAN +#include + +std::wstring logs_filepath = L"./crash_test/zxc.txt"; + + +static LONG WINAPI exception_handler(LPEXCEPTION_POINTERS ex_pointers) +{ + std::ifstream file(logs_filepath); + if (file.is_open()) { + std::string line{}; + std::getline(file, line); + file.close(); + + if (line.size()) { + std::cout << "Success!" << std::endl; + exit(0); + } + } + + std::cerr << "Failed!" << std::endl; + exit(1); +} + + +int main() +{ + // simululate the existence of previous handler + SetUnhandledExceptionFilter(exception_handler); + + if (!remove_file(logs_filepath)) { + std::cerr << "failed to remove log" << std::endl; + return 1; + } + + if (!crash_printer::init(logs_filepath)) { + std::cerr << "failed to init" << std::endl; + return 1; + } + + // simulate a crash + volatile int * volatile ptr = nullptr; + *ptr = 42; + + return 0; +}