记一次crash问题分析

概要

本文介绍近期工作中遇到的一次crash,问题分析花费了不少时间,最终得以解决。

代码

cpp 复制代码
void notify_eskf_result_status() {
    // 播放vision jsondata
    if (vision_vector_size_ > 0) {
        // 和问题无关的代码
            char* new_pbdata = new char[vision_jsondata_vector_[vision_idx_].second.size()+1]; // 申请内存空间
            // 对new_pbdata进行赋值
            wrapper_->update_vision_jsondata(new_pbdata, 
                    local_time,
                    [&] {delete[] new_pbdata;}, // 传入lambda表达式,以便在定一个线程释放申请的内存空间
                    false); 
            ++vision_idx_;
     }
}

问题代码行

问题是由这一行lambda表达式带来的

\&\] {delete\[\] new_pbdata;},

问题原因

当时写代码时使用的引用捕获,所期望的是能延长new_pbdata对象的生存空间,让它在notify_eskf_result_status函数执行完成后也能存活,这样当另一个线程调用lambda表达式后仍然能访问到它,以便调用delete方法释放之前的内存。

显然我对lambda表达式的理解出现的巨大的偏差,这里的引用捕获并没有什么magic的功能,仅仅就是通常意义上的引用而已。当引用的原对象在函数结束前析构时,lambda表达式中保留的new_pbdata已经没有了生存的依据。可以推测,当程序继续执行,原先new_pbdata所在栈上的位置可以被另外其它变量所替代,这样当执行lambda表达式时,其值已经发生了改变(导致程序的崩溃)。

修改

std::bind 用来将可调用对象与其参数一起进行绑定,因此可以把问题lambda表达式改成

std::bind([](char* pbdata) { delete[] pbdata;}, new_pbdata)

把new_pbdata作为形参传入lambda表达式作为第一个参数,并使用bind在此刻进行绑定,这样后续在调用到该function时pbdata的值将和赋值时的new_pbdata相等,代码逻辑执行正确。

感想

这个case我排查了几天,最开始是寄希望通过阅读代码能发现问题,但由于认知的错误一直发现不了。然后我采取了以下措施解决问题:首先将只能在mac上的代码适配到linux上(本人对于linux的熟悉程度远大于mac),然后开发单元测试代码以便能复现问题,接着就是使用gdb和valgrind这两大杀器进行复现。即使后来问题复现,调试仍然花费了一些时间,一是代码执行在不同的线程里,二是之前的认知错误根深蒂固了,但当时我的想法就是多去尝试(打印日志),看看能不能发现一些明显的错误。

今年也解了很多crash问题,有些是别人解不了了交给我,我的一个感受就是需要耐心的去分析,人一旦着急了心态就崩了,这时根本不可能解决的了。二是还是需要一些辅助的工具和手段,有些问题隐藏得比较深,仅仅code review是不够了,即使需要花费额外的精力去做。

相关推荐
同勉共进3 小时前
虚函数表里有什么?(二)——普通单继承下的虚函数表
c++·单继承·虚函数表·dynamic_cast·rtii
永恒迷星.by5 小时前
文件操作(c语言)
c语言·c++·算法·文件操作
Zhichao_977 小时前
【UE5 C++课程系列笔记】32——读Json文件并解析
c++·ue5
点云SLAM7 小时前
C++20新增内容
c++·算法·c++20·c++ 标准库
照书抄代码7 小时前
C++11可变参数模板单例模式
开发语言·c++·单例模式·c++11
No0d1es7 小时前
CCF GESP C++编程 四级认证真题 2025年3月
开发语言·c++·青少年编程·gesp·ccf·四级·202503
No0d1es8 小时前
CCF GESP C++编程 五级认证真题 2025年3月
开发语言·c++·青少年编程·gesp·ccf·五级·2025年3月
shuaixio8 小时前
【C++代码整洁之道】第九章 设计模式和习惯用法
c++·设计模式·设计原则·常见设计模式·习惯用法
the_nov9 小时前
25.Reactor
linux·c++
神里流~霜灭10 小时前
数据结构:二叉树(三)·(重点)
c语言·数据结构·c++·算法·二叉树·红黑树·完全二叉树