繁体   English   中英

调试 MFC header 代码不适用于 Visual Studio 2019

[英]Debugging into MFC header code does not work with Visual Studio 2019

TL;DR :调试MFC ( CString ) header 代码在我的两台机器上不起作用,据我所知,这是由于这些头文件的特殊编译方式。

通过反汇编输入时,逐步通过 MFC header 代码有效,但设置 brealpoints 不起作用。

我正在寻找解决方法或至少确认我的分析。


系统:

  • Visual Studio 2019 专业版 16.9.6
  • Windows 10 / 1809 企业 LTSC

设置:(我很抱歉这很长。)

  • 创建 Visual Studio 2019 示例 MFC 应用程序项目(SDI 应用程序)

  • 确保在 Options -> Debugging -> General 下关闭Enable Just My Code

  • 将构建配置设置为 Debug/x64(没有区别,但让我们都留在同一页面上)

  • 导航到MFCApplication1.cpp -> CMFCApplication1App::InitInstance()

  • 像这样插入一个 CString init:

     ... InitCommonControlsEx(&InitCtrls); CWinAppEx::InitInstance(); // please put breakpoint 1 here // Add this line and set breakpoints CString this_is_text(L"Debugging into CString Header does not work;"); // breakpoint 2 here

现在,您可以在调试器下启动程序,并且应该在第一个断点处停止:

InitInstance 中的第一个断点

现在,确保所有符号都已加载,最简单的方法是通过调用堆栈完成:

带有上下文菜单和标记的加载符号条目的完全选择的调用堆栈

只需 select 调用堆栈 window 中的所有行,然后在上下文菜单中点击加载符号。 之后调用堆栈应大致如下所示:

     >  MFCApplication1.exe!CMFCApplication1App::InitInstance() Line 75 C++
        mfc140ud.dll!AfxWinMain(HINSTANCE__ * hInstance=0x00007ff7b5070000, ...) Line 37    C++
        MFCApplication1.exe!wWinMain(HINSTANCE__ * hInstance=0x00007ff7b5070000, ...) Line 26   C++
        MFCApplication1.exe!invoke_main() Line 123  C++
        MFCApplication1.exe!__scrt_common_main_seh() Line 288   C++
        MFCApplication1.exe!__scrt_common_main() Line 331   C++
        MFCApplication1.exe!wWinMainCRTStartup(void * __formal=0x000000c2b7084000) Line 17  C++
        kernel32.dll!BaseThreadInitThunk()  Unknown
        ntdll.dll!RtlUserThreadStart()  Unknown

现在,您可以尝试进入(可能是 F11) CWinAppEx::InitInstance() function,它应该可以正常工作,让您进入mfc140ud.dll:CWinApp::InitInstance() Line 394行。

再次退出,然后尝试进入CString ctor:

CString ctor 处的断点

这在我的机器上不起作用!

然而,我能做的是(从上面的观点)切换到反汇编视图,进入那里的call并以这种方式进入 header 代码:

反汇编步骤进入 MFC 标头 copde

然后我可以成功地通过(但永远不会进入)MFC header 代码。 尝试设置断点会导致错误:

当前不会命中断点。 没有调试器代码类型的可执行代码与此行相关联。 可能的原因包括...

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\atlmfc\include\cstringt.h

断点错误

这就是我所在的位置。

分析

从 MFC 代码中我们可以看到,我们可以进入“常规”cpp 代码,但是一旦我们尝试进入(或设置断点)这个CStringt.h中的代码,它就会中断。

特殊之处:这是模板header代码,但执行的代码(如反汇编所示)仍然不在用户模块中,而是在mfc###.dll 我认为他们使用预处理器做了一些聪明的技巧(参见defined(_MFC_DLL_BLD)和一些类似的),这使得 header 文件的这种多重使用成为可能,也许这也是破坏调试器的原因。

问题

  • 这是一个已知问题吗,所有 VS2019 安装都会发生这种情况,我的设置有什么特殊之处吗?
  • 也许在较新的 VS 版本中修复?
  • 如果这实际上被破坏了,除了在进入 MFC 接头时不断切换到反汇编视图之外,还有什么可用的解决方法。

这里最有趣的答案实际上是关于为什么会中断 - 调试器在哪里感到困惑? 这是调试库代码时重新define代码的普遍问题吗?

MSVC 附带的源不匹配。

我认为会发生这种情况,因为 DLL 使用 Windows 更新或新的 vcredist 进行了更新,但 Visual Studio 包含的内容未更新。 如果您使用/MT/MTd并静态链接 MFC,则问题不会持续存在。

如果您愿意,可能可以将此报告给http://developercommunity.visualstudio.com

解决方法 1

执行@selbie 描述的步骤:

  1. 在我要进入的代码行上设置断点。
  2. 到达断点后,在编辑器 window 和 select 中右键单击“Go To Disassemly”。
  3. 在反汇编模式下,单步执行直到到达call语句。 [...]您可以通过再次右键单击并选择“转到源代码”来退出反汇编模式。

(跳过与此问题无关的部分)

然后手动拿起 header 的位置,调试器会告诉它不匹配。 虽然差异似乎微不足道,因此 header 是可用的。

解决方法 2

静态链接MFC,用/MT/MTd编译

解决方法 3

ATL 有一个类似的CString不会受到该问题的影响:

#include <atlbase.h>
#include <atlstr.h>

int main() {
    ATL::CString this_is_text("Debugging into CString header works");
}

分析在某个时候出现了偏差,但我们最终在这里发现了问题的一部分:

Require source files to exactly match the original version选项:

调试常规选项

是问题所在,但以一种非常奇特的方式:

当您不需要匹配源文件时(即禁用此默认选项),则会发生 OP 的错误行为:调试器无法再将符号与cstringt.h文件匹配。

不幸的是,我在两台机器上都禁用了这个。 拉入第三台机器表明我们可以设置断点(尽管 F11 仍然不起作用)并且通过比较 VS 设置的 xml 导出,我们发现这是不同的。

所以,长话短说:对我们来说,为了能够在(未修改的)MFC 标头中设置断点,我们需要启用Require source files to exactly match..选项。

如果该选项被禁用,这意味着调试器的行为更加宽松,它不再起作用。

而且,是的,我们仔细检查了它在C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Tools\MSVC\14.28.29910\atlmfc\include\cstringt.h处始终是相同的源文件

step-into/F11 的谜团仍然存在,但我想这最好被带到一个单独的问题上。

在 Tools->Options->Debugging 中取消选中 Enable Just My Code 选项

在此处输入图像描述

我知道这适用于 c++ std:: 库代码调试。 当我忘记取消选中此选项时,我执行的另一种技术类似于您上面描述的。

  1. 在我要进入的代码行上设置断点。
  2. 到达断点后,在编辑器 window 和 select 中右键单击“Go To Disassemly”。
  3. 在反汇编模式下,单步执行直到到达call语句。 这通常是标准库。 最终,您将导航到汇编和系统代码源的混合。 您可以通过再次右键单击并选择“转到源代码”来退出反汇编模式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM