在Google Test中,如何高效生成触发seg fault的测试用例列表?
高效定位触发段错误的单元测试用例列表方法
针对大规模合并后多测试用例触发segfault的问题,不用逐个排除重跑,试试这些更高效的方法:
1. 二分法批量排查(最快缩小范围)
利用Google Test的--gtest_filter参数做二分排查:
- 先把所有测试用例分成两组(比如按命名前缀划分,或用脚本生成两组过滤规则),例如
--gtest_filter=TestA*和--gtest_filter=-TestA* - 运行其中一组,若出现segfault,说明故障在该组内,继续对该组二分;若未出现,则去另一组排查
- 重复该过程,直到定位到所有触发segfault的单个用例。这种方法时间复杂度为O(logN),比逐个排除的O(N)效率高得多,1000个用例最多仅需10轮即可完成。
2. 调试器+GTest内置参数实时记录崩溃用例
用调试器配合GTest断点参数,无需重复跑整个套件:
- 用gdb启动测试程序:
gdb ./your_test_binary - 在gdb中运行时添加GTest参数:
run --gtest_break_on_failure - 当segfault发生时,调试器会暂停,执行以下命令打印当前测试用例:
p testing::UnitTest::GetInstance()->current_test_info()->test_case_name() p testing::UnitTest::GetInstance()->current_test_info()->name() - 记录该用例后,用
continue命令让程序继续运行;若崩溃后无法继续,重启程序时用--gtest_filter=-TestCaseName.TestName排除已记录的用例即可。
3. 给测试用例加前置日志,一次跑全记录崩溃点
修改测试框架前置逻辑,自动记录每个运行的用例:
- 编写一个基础测试类,让所有测试用例继承它,在
SetUp()方法中添加日志输出:class BaseTest : public testing::Test { protected: void SetUp() override { const auto* test_info = testing::UnitTest::GetInstance()->current_test_info(); std::ofstream log_file("test_run.log", std::ios::app); log_file << "Running test: " << test_info->test_case_name() << "." << test_info->name() << std::endl; } }; - 重新编译测试程序后运行,程序segfault时,日志文件的最后一行就是触发崩溃的用例。将其加入排除列表后,再次运行剩余用例,重复直到所有用例跑完。这种方法无需频繁重启整个套件,能大幅减少重复运行时间。
4. 用AddressSanitizer定位根源(顺带记录触发用例)
若核心目标是修复问题而非单纯生成列表,用ASAN能快速找到内存错误根源:
- 编译时添加ASAN参数:
-fsanitize=address -g - 运行测试程序,ASAN会在segfault发生时输出详细错误堆栈,包括导致内存问题的代码行,同时也会打印当前运行的测试用例名字。修复根源问题后,所有触发segfault的用例会自动恢复正常,省去逐个排查的麻烦。
内容的提问来源于stack exchange,提问作者Chuu
相关产品推荐
相关产品推荐

