#include "gtest/gtest.h" #include "src/errors.cpp" #include #include #include // 用于捕获信号的跳转缓冲区 static jmp_buf env; // 信号处理函数 void signal_handler(int sig) { (void)sig; longjmp(env, 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(env) == 0) { // 这应该触发段错误 test_null_pointer(); // 如果执行到这里,说明没有触发段错误,测试失败 FAIL() << "Expected segmentation fault from null pointer dereference"; } else { // 成功捕获到段错误,测试通过 SUCCEED(); } // 恢复旧的信号处理器 sigaction(SIGSEGV, &old_sa, NULL); } // 测试数组越界访问 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(env) == 0) { // 这应该触发段错误 test_array_out_of_bounds(); // 如果执行到这里,说明没有触发段错误,测试失败 FAIL() << "Expected segmentation fault from array out of bounds access"; } else { // 成功捕获到段错误,测试通过 SUCCEED(); } // 恢复旧的信号处理器 sigaction(SIGSEGV, &old_sa, NULL); } // 测试未初始化变量使用 TEST(ErrorsTest, TestUninitializedVar) { // 未初始化变量的行为是未定义的,可能不会立即崩溃 // 我们只能验证函数可以执行而不崩溃(尽管行为未定义) // 设置信号处理器来捕获可能的段错误 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(env) == 0) { // 执行函数,行为未定义但应该不会立即崩溃 test_uninitialized_var(); // 如果执行到这里,说明没有立即崩溃 // 对于未初始化变量,我们无法预测确切行为,所以只验证函数可以执行 SUCCEED(); } else { // 如果捕获到段错误,也记录为通过(因为未定义行为可能包括崩溃) SUCCEED(); } // 恢复旧的信号处理器 sigaction(SIGSEGV, &old_sa, NULL); } // 测试所有错误函数一起执行 TEST(ErrorsTest, TestAllErrorFunctions) { // 这个测试验证所有错误函数都可以被调用 // 注意:这些函数都会导致未定义行为,所以我们需要单独测试它们 // 这里只是验证测试框架可以编译和链接这些函数 // 我们只验证函数指针不为空,不实际调用函数 void (*func1)() = test_null_pointer; void (*func2)() = test_array_out_of_bounds; void (*func3)() = test_uninitialized_var; EXPECT_NE(func1, nullptr); EXPECT_NE(func2, nullptr); EXPECT_NE(func3, nullptr); } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }