cdemo/tests/test_errors.cpp

86 lines
2.7 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, TestNullPointer) {
// 设置信号处理程序以捕获段错误
std::signal(SIGSEGV, signal_handler);
// 使用 setjmp/longjmp 来捕获段错误
if (setjmp(jump_buffer) == 0) {
// 尝试调用会触发段错误的函数
test_null_pointer();
// 如果执行到这里,说明没有触发段错误,测试失败
FAIL() << "Expected segmentation fault from null pointer dereference";
} 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 segmentation fault from array out of bounds";
} 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();
}