77 lines
2.5 KiB
C++
77 lines
2.5 KiB
C++
#include "gtest/gtest.h"
|
||
#include "src/errors.cpp"
|
||
#include <iostream>
|
||
#include <csignal>
|
||
#include <csetjmp>
|
||
|
||
// 信号处理工具,用于捕获程序崩溃
|
||
static jmp_buf jump_buffer;
|
||
void signal_handler(int sig) {
|
||
(void)sig;
|
||
longjmp(jump_buffer, 1);
|
||
}
|
||
|
||
// 测试空指针解引用
|
||
TEST(ErrorsTest, TestNullPointerTriggersCrash) {
|
||
// 设置信号处理器以捕获段错误
|
||
struct sigaction sa_old;
|
||
struct sigaction sa_new;
|
||
sa_new.sa_handler = signal_handler;
|
||
sigemptyset(&sa_new.sa_mask);
|
||
sa_new.sa_flags = 0;
|
||
sigaction(SIGSEGV, &sa_new, &sa_old);
|
||
|
||
// 如果 setjmp 返回 0,表示首次设置跳转点
|
||
// 如果返回非 0,表示从 signal_handler 跳转回来
|
||
if (setjmp(jump_buffer) == 0) {
|
||
// 尝试调用会崩溃的函数
|
||
test_null_pointer();
|
||
// 如果执行到这里,说明没有触发崩溃,测试失败
|
||
FAIL() << "Expected test_null_pointer to cause a segmentation fault.";
|
||
} else {
|
||
// 成功捕获到崩溃信号
|
||
SUCCEED();
|
||
}
|
||
|
||
// 恢复原来的信号处理器
|
||
sigaction(SIGSEGV, &sa_old, nullptr);
|
||
}
|
||
|
||
// 测试数组越界访问
|
||
TEST(ErrorsTest, TestArrayOutOfBoundsTriggersCrash) {
|
||
struct sigaction sa_old;
|
||
struct sigaction sa_new;
|
||
sa_new.sa_handler = signal_handler;
|
||
sigemptyset(&sa_new.sa_mask);
|
||
sa_new.sa_flags = 0;
|
||
sigaction(SIGSEGV, &sa_new, &sa_old);
|
||
|
||
if (setjmp(jump_buffer) == 0) {
|
||
test_array_out_of_bounds();
|
||
FAIL() << "Expected test_array_out_of_bounds to cause a segmentation fault.";
|
||
} else {
|
||
SUCCEED();
|
||
}
|
||
|
||
sigaction(SIGSEGV, &sa_old, nullptr);
|
||
}
|
||
|
||
// 测试未初始化变量(行为未定义,可能不会崩溃,但结果不可预测)
|
||
// 我们主要验证函数可以执行而不抛出异常(尽管逻辑错误)
|
||
TEST(ErrorsTest, TestUninitializedVarExecutesWithoutCrash) {
|
||
// 由于使用未初始化变量是未定义行为,
|
||
// 它可能不会立即导致崩溃。
|
||
// 我们只是确保函数调用本身不会因为我们的测试框架而失败。
|
||
// 注意:这并不能证明函数是正确的,只是它不会在常见环境下崩溃。
|
||
// 这是一个演示如何测试具有未定义行为函数的例子。
|
||
EXPECT_NO_FATAL_FAILURE(test_uninitialized_var());
|
||
// 由于输出取决于未初始化的内存,我们无法断言具体的输出。
|
||
// 测试通过仅意味着函数执行完毕。
|
||
}
|
||
|
||
// 主函数
|
||
int main(int argc, char **argv) {
|
||
::testing::InitGoogleTest(&argc, argv);
|
||
return RUN_ALL_TESTS();
|
||
}
|