#include "gtest/gtest.h" #include "src/errors.cpp" #include #include #include // 用于捕获信号的跳转缓冲区 static jmp_buf jump_buffer; // 信号处理函数 void signal_handler(int signal) { // 跳转回测试点,避免程序崩溃 longjmp(jump_buffer, 1); } // 测试空指针解引用 TEST(ErrorsTest, TestNullPointer) { // 设置信号处理器来捕获段错误 std::signal(SIGSEGV, signal_handler); // 使用setjmp/longjmp来捕获可能的崩溃 if (setjmp(jump_buffer) == 0) { // 尝试调用会解引用空指针的函数 test_null_pointer(); // 如果执行到这里,说明没有触发段错误,测试失败 FAIL() << "Expected null pointer dereference to cause a crash"; } else { // 成功捕获到段错误,测试通过 SUCCEED(); } // 恢复默认信号处理器 std::signal(SIGSEGV, SIG_DFL); } // 测试数组越界访问 TEST(ErrorsTest, TestArrayOutOfBounds) { // 设置信号处理器来捕获段错误 std::signal(SIGSEGV, signal_handler); // 使用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(); } // 恢复默认信号处理器 std::signal(SIGSEGV, SIG_DFL); } // 测试未初始化变量使用 TEST(ErrorsTest, TestUninitializedVar) { // 对于未初始化变量的使用,行为是未定义的 // 我们无法可靠地测试其行为,但可以验证函数能够被调用而不崩溃 // 注意:这并不保证正确性,只是验证基本可执行性 // 设置信号处理器以防万一 std::signal(SIGSEGV, signal_handler); // 使用setjmp/longjmp来捕获可能的崩溃 if (setjmp(jump_buffer) == 0) { // 尝试调用使用未初始化变量的函数 test_uninitialized_var(); // 如果执行到这里,说明函数至少没有立即崩溃 // 对于未定义行为,我们无法做出更多断言 SUCCEED(); } else { // 如果捕获到信号,也记录为通过(因为未定义行为可能包括崩溃) SUCCEED(); } // 恢复默认信号处理器 std::signal(SIGSEGV, SIG_DFL); } // 主函数 int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }