Visual Studio 断点调试之箭头偏移进错函数,捉虫记

简 述: Visual Studio 断点调试之箭头偏移进错函数,怪异现象之捉🐛记。


本文初发于 “偕臧的小站”,同步转载于此。


背景

好久没有遇到这么有趣的 Bug 了,来抓一个调试指针出现偏移错误❌的🐛。

在 C++ 实现的派生类和类中重写的两个虚函数 A、B 后,代码实写调用 A 函数,断点 Debug 调试却命中 B 函数。💻 win10 21H2 📎 Visual Studio 2019


MyCollectLogImplIMyCollectLog 的一个派生类,然后代码中调用派生类的 OnCollectLogOne 函数,但调试的箭头和断点却进入了另一 OnCollectLogArray 函数;十分怪异之。

class IMyCollectLog : IMyUnknown {
public:
    virtual long STDCALLTYPE OnCollectLogOne(const char* sKey, IMyBundle*) = 0;
    virtual long STDCALLTYPE OnCollectLogArray(const char* sKey, IMyBundleArray) = 0;
};


class MyCollectLogImpl : public CloudService::IMyCollectLog
{
public:
    long STDCALLTYPE OnCollectLogOne(const char* sKey, IMyBundle* pBundle) override {
        if (!sKey || !pBundle)
            return 0;

         // TODO: do something
        return 0;
    }

    long STDCALLTYPE OnCollectLogArray(const char* sKey, IMyBundleArray* pBundleArray) override {
        if (!sKey || !pBundleArray)
            return 0;
        
        // TODO: do something
        return 0;
    }

    // ... 定义其它成员函数和成员
};

调用处的函数为

void onInnerQueryEnd(const char* sKey, IMyBundle* pBundle) {
    if (m_setCollLogPtr.empty())
        return;

    for (auto it : m_setCollLogPtr)
        it->OnCollectLogOne(sKey, pBundle);   // *** 写的是执行 OnCollectLogOne, 而非是 OnCollectLogArray, 虽然两者行参长得很像 ***
}

用一张图来解释就是:


问题

  1. 断点调试的箭头发生偏移到其它函数。本次遇到
  2. 断点调试时,断点和箭头均无法进入某一函数内部。以前遇过

两者实际为同一根因:

『根因1』Release 编译模式下关闭优化仍有优化,空实现的函数没有对应汇编

『根因2』跨模块加载、创建对象,其 .dll 接口和 .pdb 不对应

『根因3』.dll 和 .pdb 拷贝错了源对象、移动到了错的目标路径下

『根因4』.dll 和 .pdb 拷贝到正确的目标路径,被调试的程序未重启加载此插件(大部分需要)


解决

Release 模式下编译,即使关闭优化[1],实际仍有优化。 如实现一个空的函数,就会被优化掉,反汇编窗口中可查看无对应此函数的汇编语句。『简直是大坑』。


  • Release 编译模式下关闭优化
  • 实现某一函数时却暂不实现细节(仅有 if 判断指针为空和 return 语句,细节未写),仅想调试一下框架时,可在函数中添加一句 int a = 0例子打印语句 避免被编译器优化。
  • 先切换 Debug 模式下编译,替换文件验证代码,在切回 Release 模式定位

注:

[1] Visual Studio 2019 项目属性页,“Configuration Properties - C/C++ - Optimization” 中 Optimization 设置为 Disabled (/Od);使 Release 模式的编译关闭所有优化。


系列地址

QtExamples

欢迎 star ⭐ 和 fork 🍴这个系列的 C++ / QT / DTK 学习,附学习由浅入深的目录。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

偕臧x

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值