通过colcon运行ROS2应用的GTest出现SEGFAULT段错误求助
针对ROS2 GTest段错误(返回码-11)的调试方法
直接用GDB调试测试可执行文件
跳过colcon的包装层,找到测试程序的可执行文件(一般在build/pelican/test/目录下,比如pelican_test),执行:gdb ./pelican_test进入GDB后输入
run启动测试,崩溃后输入bt查看完整调用堆栈,能精准定位到崩溃的代码行,包括析构后深层的调用逻辑(比如ROS2内部的资源清理流程)。启用AddressSanitizer编译测试
编译测试时开启内存错误检测,修改colcon编译命令:colcon build --packages-select pelican --cmake-args -DCMAKE_CXX_FLAGS="-fsanitize=address" -DCMAKE_BUILD_TYPE=Debug运行测试时,ASAN会自动输出详细的非法内存访问报告,包括内存地址、访问类型(读/写)以及对应的代码上下文,尤其适合排查析构后残留的野指针问题。
用Valgrind检测内存问题
执行测试时用Valgrind追踪内存操作:valgrind --leak-check=full --track-origins=yes ./pelican_test它能检测出内存泄漏、重复释放、使用未初始化内存等问题,帮助定位析构阶段的非法内存操作。
简化测试用例定位问题源
先写一个空的测试用例,排除测试逻辑的干扰:TEST_F(ElectionTest, EmptyTest) { // 空测试,仅验证Fixture的构造/析构流程 }如果空测试仍崩溃,说明问题出在
ElectionModule的构造或析构函数本身;如果不崩溃,再逐步添加原测试的逻辑,定位到触发崩溃的代码段。检查ROS2资源的生命周期管理
重点排查ElectionModule中ROS2组件的处理:- 是否用裸指针管理ROS2节点(正确做法是使用
rclcpp::Node::SharedPtr)? - 析构时是否正确停止了回调队列、销毁了订阅者/发布者?
- 有没有异步回调在节点析构后仍在执行,访问已销毁的对象?
可以在ElectionModule的析构函数中添加日志(比如RCLCPP_INFO),确认析构的执行顺序,同时检查ROS2的初始化/销毁是否在测试前后正确调用(比如在Fixture的SetUp中调用rclcpp::init,TearDown中调用rclcpp::shutdown)。
- 是否用裸指针管理ROS2节点(正确做法是使用
启用GTest详细输出
设置环境变量让GTest输出更细的执行步骤,确认崩溃发生的时机:GTEST_VERBOSE=1 colcon test --packages-select pelican或者在测试代码开头添加:
GTEST_FLAG_SET(verbose, "1");这样能看到每个测试用例的构造、执行、析构阶段的详细日志,进一步缩小崩溃范围。
内容的提问来源于stack exchange,提问作者slim71
相关产品推荐
相关产品推荐

