#include "gtest/gtest.h" #include "src/errors.cpp" #include #include #include // 信号处理跳转点,用于捕获程序崩溃 static jmp_buf jump_buffer; // 信号处理函数,用于捕获段错误等信号 void signal_handler(int signum) { longjmp(jump_buffer, 1); } // 测试空指针解引用 TEST(ErrorsTest, TestNullPointer) { // 设置信号处理器以捕获段错误 struct sigaction sa; struct sigaction old_sa; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; // 保存旧的信号处理器 sigaction(SIGSEGV, &sa, &old_sa); // 使用setjmp/longjmp来捕获信号 if (setjmp(jump_buffer) == 0) { // 尝试调用会触发空指针解引用的函数 test_null_pointer(); // 如果程序没有崩溃,测试失败 FAIL() << "Expected null pointer dereference to cause a crash"; } else { // 成功捕获到信号,测试通过 SUCCEED(); } // 恢复旧的信号处理器 sigaction(SIGSEGV, &old_sa, nullptr); } // 测试数组越界访问 TEST(ErrorsTest, TestArrayOutOfBounds) { // 设置信号处理器以捕获段错误 struct sigaction sa; struct sigaction old_sa; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; // 保存旧的信号处理器 sigaction(SIGSEGV, &sa, &old_sa); // 使用setjmp/longjmp来捕获信号 if (setjmp(jump_buffer) == 0) { // 尝试调用会触发数组越界的函数 test_array_out_of_bounds(); // 如果程序没有崩溃,测试失败 FAIL() << "Expected array out of bounds access to cause a crash"; } else { // 成功捕获到信号,测试通过 SUCCEED(); } // 恢复旧的信号处理器 sigaction(SIGSEGV, &old_sa, nullptr); } // 测试未初始化变量使用 TEST(ErrorsTest, TestUninitializedVar) { // 未初始化变量的行为是未定义的,可能不会立即崩溃 // 我们主要验证函数可以执行而不抛出异常 // 注意:由于行为未定义,我们无法预测具体输出 // 重定向std::cout以捕获输出 testing::internal::CaptureStdout(); // 调用函数 - 由于未定义行为,可能输出任何内容或不输出 test_uninitialized_var(); // 获取输出 std::string output = testing::internal::GetCapturedStdout(); // 由于未初始化变量的值是未定义的,我们无法做出具体断言 // 但我们可以验证函数执行没有导致程序崩溃 SUCCEED(); } // 测试边界情况:多次调用错误函数 TEST(ErrorsTest, TestMultipleErrorCalls) { // 验证连续调用多个错误函数的行为 // 注意:这些函数都会导致未定义行为,测试主要是验证它们不会相互干扰 // 设置信号处理器 struct sigaction sa; struct sigaction old_sa; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGSEGV, &sa, &old_sa); // 测试顺序调用 bool null_pointer_crashed = false; bool array_bounds_crashed = false; // 测试空指针解引用 if (setjmp(jump_buffer) == 0) { test_null_pointer(); } else { null_pointer_crashed = true; } // 重置跳转缓冲区 if (setjmp(jump_buffer) == 0) { test_array_out_of_bounds(); } else { array_bounds_crashed = true; } // 验证两个函数都如预期般导致崩溃 EXPECT_TRUE(null_pointer_crashed) << "Null pointer dereference should cause crash"; EXPECT_TRUE(array_bounds_crashed) << "Array out of bounds should cause crash"; // 恢复信号处理器 sigaction(SIGSEGV, &old_sa, nullptr); } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }