#include "gtest/gtest.h" #include "src/errors.cpp" #include #include #include // 信号处理工具,用于捕获程序崩溃 static jmp_buf jump_buffer; void signal_handler(int sig) { (void)sig; longjmp(jump_buffer, 1); } // 测试空指针解引用 TEST(ErrorsTest, TestNullPointerTriggersCrash) { // 设置信号处理器以捕获段错误 struct sigaction sa_old; struct sigaction sa_new; sa_new.sa_handler = signal_handler; sigemptyset(&sa_new.sa_mask); sa_new.sa_flags = 0; sigaction(SIGSEGV, &sa_new, &sa_old); // 如果 setjmp 返回 0,表示首次设置跳转点 // 如果返回非 0,表示从 signal_handler 跳转回来 if (setjmp(jump_buffer) == 0) { // 尝试调用会崩溃的函数 test_null_pointer(); // 如果执行到这里,说明没有触发崩溃,测试失败 FAIL() << "Expected test_null_pointer to cause a segmentation fault."; } else { // 成功捕获到崩溃信号 SUCCEED(); } // 恢复原来的信号处理器 sigaction(SIGSEGV, &sa_old, nullptr); } // 测试数组越界访问 TEST(ErrorsTest, TestArrayOutOfBoundsTriggersCrash) { struct sigaction sa_old; struct sigaction sa_new; sa_new.sa_handler = signal_handler; sigemptyset(&sa_new.sa_mask); sa_new.sa_flags = 0; sigaction(SIGSEGV, &sa_new, &sa_old); if (setjmp(jump_buffer) == 0) { test_array_out_of_bounds(); FAIL() << "Expected test_array_out_of_bounds to cause a segmentation fault."; } else { SUCCEED(); } sigaction(SIGSEGV, &sa_old, nullptr); } // 测试未初始化变量(行为未定义,可能不会崩溃,但结果不可预测) // 我们主要验证函数可以执行而不抛出异常(尽管逻辑错误) TEST(ErrorsTest, TestUninitializedVarExecutesWithoutCrash) { // 由于使用未初始化变量是未定义行为, // 它可能不会立即导致崩溃。 // 我们只是确保函数调用本身不会因为我们的测试框架而失败。 // 注意:这并不能证明函数是正确的,只是它不会在常见环境下崩溃。 // 这是一个演示如何测试具有未定义行为函数的例子。 EXPECT_NO_FATAL_FAILURE(test_uninitialized_var()); // 由于输出取决于未初始化的内存,我们无法断言具体的输出。 // 测试通过仅意味着函数执行完毕。 } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }