From 54b4a6d2e8368585f4a237a1bad5ed111d646f03 Mon Sep 17 00:00:00 2001 From: lids <1713278948@qq.com> Date: Wed, 15 Apr 2026 18:10:31 +0800 Subject: [PATCH] =?UTF-8?q?AI=20=E8=87=AA=E5=8A=A8=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/test_errors.cpp | 124 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 tests/test_errors.cpp diff --git a/tests/test_errors.cpp b/tests/test_errors.cpp new file mode 100644 index 0000000..74896c2 --- /dev/null +++ b/tests/test_errors.cpp @@ -0,0 +1,124 @@ +#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(); +}