c++ - 调试到 MFC header 代码不适用于 Visual Studio 2019

标签 c++ visual-studio debugging mfc pdb

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

在通过反汇编输入时单步执行 MFC 头代码,但设置 brealpoints 不起作用。

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


系统:

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

设置:(对于这段时间太长,我深表歉意。)

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

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

  • 将构建配置设置为 Debug/x64(没有区别,但让我们保持一致)

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

  • 像这样插入一个 CString 初始化:

      ...
      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
    

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

First breakpoint in InitInstance

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

Fully selected Call Stack with Context Menu and marked Load Symbols entry

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

     >  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() 函数,它应该可以工作问题,让您进入 mfc140ud.dll!CWinApp::InitInstance() Line 394 - 没问题。

再次单步执行,然后尝试单步执行 CString 构造函数:

Breakpoint at CString ctor

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

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

Disassembly step into MFC header copde

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

The breakpoint will not currently be hit. No executable code of the debugger's code type is associated with this line. Possible causes include ...

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

Breakpoint error

这就是我所在的地方。

分析:

从 MFC 代码中我们可以看到,我们可以单步执行“常规”cpp 代码,但是一旦我们尝试单步执行(或设置断点)此CStringt.h 它中断了。

这里的特殊之处:这是模板 header 代码,执行的代码(如反汇编所示)仍然不在用户模块中,而是在 mfc###.dll!我认为他们对预处理器做了一些巧妙的技巧(请参阅 defined(_MFC_DLL_BLD) 等),从而实现了对头文件的多次使用,也许这也是破坏调试器的原因。

问题:

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

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

最佳答案

MSVC 附带的源不匹配。

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

可能这可以报告给http://developercommunity.visualstudio.com如果你关心的话。

解决方法 1

执行@selbie 描述的步骤:

  1. Set a breakpoint on the line of code I want to step into.
  2. When the breakpoint is reached, right click in the editor window and select "Go To Disassemly".
  3. In disassembly mode, step over until you get to a call statement. [...] You can flip out of disassembly mode by right-clicking again and selecting "go to source code".

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

然后手动拾取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");
}

关于c++ - 调试到 MFC header 代码不适用于 Visual Studio 2019,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70182512/

相关文章:

c - 就地重新启动 Windows 进程,保留进程 ID 和句柄

c# - 如何在具有许多绑定(bind)的巨大 View 中找到错误的绑定(bind)?

.net - 如何在没有返回变量的情况下调试 VB.NET 计算函数返回

ios - 如何强制 iOS 应用程序挂起而不是崩溃?

c++ - 如何提高集成模型的推理时间

c# - 以编程方式修改 Sharepoint Online Excel 文件

.net - 在 Visual Studio 工具箱中安装 .NET Framework 控件

c++ - C++ std::string::compare() 与字符串运算符之间的不一致

c++ - 组合两个不同类型的 std::lists:可能吗?

C++,解析二进制注册表文件 (regf)