From ce28f1baf1c24503d11d09eaf1f21567be6b666f Mon Sep 17 00:00:00 2001 From: lids <1713278948@qq.com> Date: Wed, 15 Apr 2026 17:54:10 +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 | 139 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 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..597c313 --- /dev/null +++ b/tests/test_errors.cpp @@ -0,0 +1,139 @@ +#include "gtest/gtest.h" +#include "src/errors.cpp" +#include +#include +#include + +// 全局变量用于信号处理 +static std::jmp_buf jump_buffer; +static volatile sig_atomic_t gSignalStatus = 0; + +// 信号处理函数 +void signal_handler(int signal) { + gSignalStatus = signal; + std::longjmp(jump_buffer, 1); +} + +// 测试夹具类 +class ErrorsTest : public ::testing::Test { +protected: + void SetUp() override { + // 保存旧的信号处理器 + old_sigsegv_handler = std::signal(SIGSEGV, signal_handler); + old_sigabrt_handler = std::signal(SIGABRT, signal_handler); + gSignalStatus = 0; + } + + void TearDown() override { + // 恢复旧的信号处理器 + std::signal(SIGSEGV, old_sigsegv_handler); + std::signal(SIGABRT, old_sigabrt_handler); + } + + // 检查是否捕获到预期的信号 + bool expectSignal(int expected_signal) { + if (setjmp(jump_buffer) == 0) { + // 第一次进入,执行可能崩溃的代码 + return false; + } else { + // 从信号处理器跳转回来 + return gSignalStatus == expected_signal; + } + } + +private: + using SignalHandler = void (*)(int); + SignalHandler old_sigsegv_handler; + SignalHandler old_sigabrt_handler; +}; + +// 测试 test_null_pointer 函数 +TEST_F(ErrorsTest, TestNullPointerTriggersSegmentationFault) { + // 这个测试期望函数触发段错误(SIGSEGV) + // 由于我们设置了信号处理器,测试不会崩溃 + bool caught_signal = expectSignal(SIGSEGV); + if (!caught_signal) { + // 如果没有通过信号捕获,直接调用函数(这会导致测试进程崩溃) + // 但在我们的测试夹具中,这应该被信号处理器捕获 + test_null_pointer(); + } + // 验证我们捕获到了段错误信号 + EXPECT_TRUE(caught_signal) << "Expected SIGSEGV signal from null pointer dereference"; +} + +TEST_F(ErrorsTest, TestNullPointerUndefinedBehavior) { + // 这个测试验证空指针解引用是未定义行为 + // 在某些平台上,可能不会立即崩溃,但行为是未定义的 + // 我们主要验证函数可以编译和链接 + SUCCEED() << "test_null_pointer function exists and can be called"; +} + +// 测试 test_array_out_of_bounds 函数 +TEST_F(ErrorsTest, TestArrayOutOfBoundsTriggersMemoryError) { + // 数组越界访问可能触发段错误(SIGSEGV)或其他内存错误 + bool caught_signal = expectSignal(SIGSEGV); + if (!caught_signal) { + test_array_out_of_bounds(); + } + // 数组越界是未定义行为,可能不会立即崩溃 + // 但我们期望在大多数实现中会触发内存错误 + if (caught_signal) { + EXPECT_TRUE(caught_signal) << "Expected memory error from array out of bounds access"; + } else { + // 如果没有崩溃,记录警告 + ADD_FAILURE() << "Array out of bounds access did not trigger immediate crash (undefined behavior)"; + } +} + +TEST_F(ErrorsTest, TestArrayOutOfBoundsUndefinedBehavior) { + // 验证数组越界访问是未定义行为 + // 测试函数的存在性和可调用性 + SUCCEED() << "test_array_out_of_bounds function exists and can be called"; +} + +// 测试 test_uninitialized_var 函数 +TEST_F(ErrorsTest, TestUninitializedVarUndefinedBehavior) { + // 使用未初始化变量是未定义行为 + // 这个测试主要验证函数可以编译和运行 + // 由于行为未定义,我们无法预测具体输出 + + // 重定向std::cout以捕获输出 + testing::internal::CaptureStdout(); + + // 调用函数 - 行为未定义,可能输出任何内容或不输出 + test_uninitialized_var(); + + std::string output = testing::internal::GetCapturedStdout(); + + // 由于val未初始化,其值不确定,因此输出也不确定 + // 我们只验证函数执行没有崩溃 + SUCCEED() << "test_uninitialized_var executed without crash (output: '" << output << "')"; +} + +TEST_F(ErrorsTest, TestUninitializedVarRandomBehavior) { + // 多次调用函数,观察未初始化变量的随机行为 + // 注意:这仍然是未定义行为,不仅仅是随机 + + std::set outputs; + const int num_runs = 10; + + for (int i = 0; i < num_runs; ++i) { + testing::internal::CaptureStdout(); + test_uninitialized_var(); + std::string output = testing::internal::GetCapturedStdout(); + outputs.insert(output); + } + + // 未初始化变量可能导致不同输出或相同输出 + // 我们只记录观察到的行为 + std::cout << "Observed " << outputs.size() << " different outputs from " + << num_runs << " runs of test_uninitialized_var" << std::endl; + + SUCCEED() << "test_uninitialized_var shows undefined behavior across multiple runs"; +} + +// 主函数 +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}