简 述: Visual Studio
断点调试之箭头偏移进错函数,怪异现象之捉?记。
[TOC]
本文初发于 “偕臧的小站“,同步转载于此。
背景
好久没有遇到这么有趣的 Bug 了,来抓一个调试指针出现偏移错误❌的?。
在 C++ 实现的派生类和类中重写的两个虚函数 A、B 后,代码实写调用 A 函数,断点 Debug 调试却命中 B 函数。? win10 21H2
? Visual Studio 2019
MyCollectLogImpl
为 IMyCollectLog
的一个派生类,然后代码中调用派生类的 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, 虽然两者行参长得很像 ***}
用一张图来解释就是:
问题
- 断点调试的箭头发生偏移到其它函数。本次遇到
- 断点调试时,断点和箭头均无法进入某一函数内部。以前遇过
两者实际为同一根因。
解决
- Release 编译模式下关闭优化
- 实现某一函数时却暂不实现细节(仅有 if 判断指针为空和 return 语句,细节未写),仅想调试一下框架时,可在函数中添加一句
int a = 0
或例子打印语句
避免被编译器优化。 - 先切换 Debug 模式下编译,替换文件验证代码,在切回 Release 模式定位
Release 模式下编译,即使关闭优化[1],实际仍有优化。 如实现一个空的函数,就会被优化掉,反汇编窗口中可查看无对应此函数的汇编语句。『简直是大坑』。
注:
[1] Visual Studio 2019 项目属性页,”Configuration Properties – C/C++ – Optimization” 中 Optimization
设置为 Disabled (/Od)
;使 Release 模式的编译关闭所有优化。
本文转自: https://ifmet.cn/posts/83002d8f/
本站仅做收录,版权归原作者所有。