
文章图片

文章图片
有时候在解决一些问题的时候需要使用到调试 , 这个场景很常见 , 我们在代码的某个地方设置一个断点 , 然后步进到一个函数内部单步调试 , 但是你会发现 , 调试器会显示你在另外一个函数中 。 这是咋回事儿?我们先来看看下面的一段代码 。
当你步进到调用p->GetValue()的地方时 , 你会发现调试器显示当前在Class1::GetQ中 。 那么 , 发生了什么呢?
这是因为 , 从链接器的视角来看 , 在代码生成阶段 , 链接器合并了所有相同的函数 , 如下图所示:
【小米科技|为什么调试器会显示错误的函数】请注意 , 在对象代码级别上 , 这两个函数是完全相同的 。 (请注意 , 两个函数在目标代码级别是否相同很大程度上取决于你使用的编译器版本以及优化标志 。 当你使用模板时 , 不同函数的相同代码生成频率非常高 。 )
因此 , 链接器说:”好吧 , 拥有两个相同的功能有什么意义? 我将只保留一份并用它来代表 Class1::GetQ 和 Class2::GetValue 。 ”
请注意 , 这两个函数已合并:函数的地址是相同的 。只是这一段代码有两个名字 。因此 , 当调试器看到你已跳转到 0x010010d6 时 , 它不知道应该使用哪个名称 , 所以它只是选择了其中的一个 。
这就是为什么看起来你跳错了函数 。
这就是所谓的“相同COMDAT折叠”(identical COMDAT folding) , 你可以将 /OPT:NOICF 标志传递给链接器来禁止此优化 。
总结在开发TopomelBox的过程中 , 有一天突发奇想 , 想去了解所有编译开关的意思 。
有些很容易理解 , 比如各种头文件目录等 , 但有些链接器开关实在是难以理解 , 今天的这个”COMDAT Folding”就是其中的一个 。
搞开发这条路 , 还是任重而道远啊 。
最后Raymond Chen的《The Old New Thing》是我非常喜欢的博客之一 , 里面有很多关于Windows的小知识 , 对于广大Windows平台开发者来说 , 确实十分有帮助 。
本文来自:《Why does the debugger show me the wrong function?》
- 手机同质化一直非常的严重|小米13系列好评满满,骁龙8gen2比苹果a16更强
- 2022年已经进入到了尾声|小米13刚发布,中国移动送出喜讯:5G功耗第一,综合评测第一
- 12月13日消息|小米13系列手机明日开售售价4599元
- 雷军宣布小米13系列将很快登陆全球市场:国外用户激动坏了在中国市场发布后|雷军宣布小米13系列很快登陆全球市场:国外用户激动坏了
- 小米|仅巴掌大小的桌面神器!小米迷你主机图赏
- 小米|双尺寸旗舰对标苹果!小米13系列明日开售:3999元起
- 小米|插头“打架”问题终于解决:小米插线板8位总控版上架开售
- 一个新品牌是否成功|小米13手机的优势在哪里?
- 科技在不断进步|宝砾微pl56002助力快充市场繁荣发展
- 南京酷科电子科技有限公司作为小米科技公司旗下的生态链企业之一|酷科65wgan充电器测试模块测试模块主要测试
