#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); } // 测试夹具类 class ErrorsTest : public ::testing::Test { protected: // 保存原始信号处理器 void (*original_sigsegv_handler)(int); void (*original_sigabrt_handler)(int); void SetUp() override { // 安装自定义信号处理器 original_sigsegv_handler = signal(SIGSEGV, signal_handler); original_sigabrt_handler = signal(SIGABRT, signal_handler); } void TearDown() override { // 恢复原始信号处理器 signal(SIGSEGV, original_sigsegv_handler); signal(SIGABRT, original_sigabrt_handler); } }; // 测试 test_null_pointer 函数 TEST_F(ErrorsTest, TestNullPointerTriggersSignal) { // 设置跳转点,如果发生信号则跳转回此处 if (setjmp(jump_buffer) == 0) { // 尝试执行会触发信号的代码 test_null_pointer(); // 如果执行到这里,说明没有触发信号,测试失败 FAIL() << "Expected test_null_pointer to trigger a signal but it didn't"; } else { // 成功捕获到信号 SUCCEED(); } } // 测试 test_array_out_of_bounds 函数 TEST_F(ErrorsTest, TestArrayOutOfBoundsTriggersSignal) { if (setjmp(jump_buffer) == 0) { test_array_out_of_bounds(); FAIL() << "Expected test_array_out_of_bounds to trigger a signal but it didn't"; } else { SUCCEED(); } } // 测试 test_uninitialized_var 函数 // 注意:使用未初始化变量不一定会触发信号,行为是未定义的 // 我们只能验证函数可以执行而不崩溃(在某些平台上) TEST_F(ErrorsTest, TestUninitializedVarDoesNotCrash) { // 这个测试可能通过,也可能失败,取决于编译器和运行时环境 // 我们主要验证函数可以调用而不导致程序终止 EXPECT_NO_FATAL_FAILURE(test_uninitialized_var()); } // 边界条件测试:验证正常数组访问不会触发信号 TEST_F(ErrorsTest, TestNormalArrayAccess) { // 创建一个简单的测试来验证正常数组访问 int arr[3] = {1, 2, 3}; if (setjmp(jump_buffer) == 0) { // 正常访问数组元素 std::cout << "Normal array access: " << arr[0] << std::endl; std::cout << "Normal array access: " << arr[1] << std::endl; std::cout << "Normal array access: " << arr[2] << std::endl; SUCCEED(); } else { FAIL() << "Normal array access triggered a signal unexpectedly"; } } // 特殊场景:验证空指针检查 TEST_F(ErrorsTest, TestNullPointerCheck) { int* p = nullptr; if (setjmp(jump_buffer) == 0) { // 尝试解引用空指针 *p = 10; FAIL() << "Expected null pointer dereference to trigger a signal but it didn't"; } else { SUCCEED(); } } // 特殊场景:验证数组边界检查 TEST_F(ErrorsTest, TestArrayBoundaryCheck) { int arr[3] = {1, 2, 3}; if (setjmp(jump_buffer) == 0) { // 尝试访问刚好越界的元素(在某些系统上可能不会立即崩溃) volatile int value = arr[3]; // 刚好越界 // 如果执行到这里,测试可能通过,也可能失败 // 这取决于编译器和运行时环境 std::cout << "Array access at index 3 returned: " << value << std::endl; // 我们不标记为失败,因为行为是未定义的 SUCCEED(); } else { // 成功捕获到信号 SUCCEED(); } } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }