#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, 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); // 设置跳转点 if (setjmp(jump_buffer) == 0) { // 尝试调用会触发段错误的函数 test_null_pointer(); // 如果执行到这里,说明没有触发段错误 FAIL() << "Expected segmentation fault but none occurred"; } 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); // 设置跳转点 if (setjmp(jump_buffer) == 0) { // 尝试调用会触发段错误的函数 test_array_out_of_bounds(); // 如果执行到这里,说明没有触发段错误 FAIL() << "Expected segmentation fault but none occurred"; } else { // 成功捕获到段错误 SUCCEED(); } // 恢复旧的信号处理程序 sigaction(SIGSEGV, &old_sa, nullptr); } // 测试未初始化变量使用 TEST(ErrorsTest, TestUninitializedVar) { // 未初始化变量的行为是未定义的,可能不会立即崩溃 // 我们只能验证函数可以执行而不崩溃 // 多次运行以增加检测到问题的机会 for (int i = 0; i < 100; ++i) { // 设置信号处理程序以捕获可能的段错误 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); // 设置跳转点 if (setjmp(jump_buffer) == 0) { // 尝试调用函数 test_uninitialized_var(); // 如果执行到这里,说明没有触发段错误 // 这是可接受的,因为未初始化变量的行为是未定义的 } else { // 如果捕获到段错误,记录但继续测试 ADD_FAILURE() << "Segmentation fault occurred at iteration " << i; } // 恢复旧的信号处理程序 sigaction(SIGSEGV, &old_sa, nullptr); } // 由于未初始化变量的行为是未定义的,我们无法做出确定的断言 // 测试通过意味着函数可以执行而不一定意味着行为正确 SUCCEED(); } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }