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

2023-11-07 09:50

本文主要是介绍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 somethingreturn 0;}long STDCALLTYPE OnCollectLogArray(const char* sKey, IMyBundleArray* pBundleArray) override {if (!sKey || !pBundleArray)return 0;// TODO: do somethingreturn 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 学习,附学习由浅入深的目录。

这篇关于Visual Studio 断点调试之箭头偏移进错函数,捉虫记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/362814

相关文章

Python函数作用域与闭包举例深度解析

《Python函数作用域与闭包举例深度解析》Python函数的作用域规则和闭包是编程中的关键概念,它们决定了变量的访问和生命周期,:本文主要介绍Python函数作用域与闭包的相关资料,文中通过代码... 目录1. 基础作用域访问示例1:访问全局变量示例2:访问外层函数变量2. 闭包基础示例3:简单闭包示例4

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

Java服务实现开启Debug远程调试

《Java服务实现开启Debug远程调试》文章介绍如何通过JVM参数开启Java服务远程调试,便于在线上排查问题,在IDEA中配置客户端连接,实现无需频繁部署的调试,提升效率... 目录一、背景二、相关图示说明三、具体操作步骤1、服务端配置2、客户端配置总结一、背景日常项目中,通常我们的代码都是部署到远程

python中的高阶函数示例详解

《python中的高阶函数示例详解》在Python中,高阶函数是指接受函数作为参数或返回函数作为结果的函数,下面:本文主要介绍python中高阶函数的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录1.定义2.map函数3.filter函数4.reduce函数5.sorted函数6.自定义高阶函数

Python中的sort方法、sorted函数与lambda表达式及用法详解

《Python中的sort方法、sorted函数与lambda表达式及用法详解》文章对比了Python中list.sort()与sorted()函数的区别,指出sort()原地排序返回None,sor... 目录1. sort()方法1.1 sort()方法1.2 基本语法和参数A. reverse参数B.

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

Python Excel 通用筛选函数的实现

《PythonExcel通用筛选函数的实现》本文主要介绍了PythonExcel通用筛选函数的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录案例目的示例数据假定数据来源是字典优化:通用CSV数据处理函数使用说明使用示例注意事项案例目的第一

JavaScript中的高级调试方法全攻略指南

《JavaScript中的高级调试方法全攻略指南》什么是高级JavaScript调试技巧,它比console.log有何优势,如何使用断点调试定位问题,通过本文,我们将深入解答这些问题,带您从理论到实... 目录观点与案例结合观点1观点2观点3观点4观点5高级调试技巧详解实战案例断点调试:定位变量错误性能分

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam