在VisualStudio 2017发布15.8预览3中,我们宣布支持我的C++代码。除了以前支持的 调用堆栈筛选 ,VisualStudio调试器现在还支持单步执行非用户代码。当您“介入”时,例如在带有自定义谓词的标准库的算法中,或在具有用户回调的Win32 API中,调试器将方便地介入您提供的谓词或回调,而不是最终调用您的代码的库代码。
在非常热情的接待 我们在std::函数调用中的调试改进 去年在CPPCON2017上宣布,该团队一直在为这个调试挑战开发一个通用的解决方案,它不需要库代码中的任何注释。15.8预览版3今天提供了此支持,我们期待您的反馈。
如何启用Just My Code stepping(JMC)
只有我的C++代码有以下要求:
- 您的程序是用一个新的MSVC编译器开关:/JMC编译的。JMC现在在所有调试配置中都默认为MSBuild项目启用,所以 确保使用最新的MSVC编译器重新编译项目 在15.8 Preview 3或更高版本中。
- 这个 加载包含用户代码的二进制文件的PDB 由调试器执行,并且
- JMC已在中启用 工具 > 选项 > 调试 > 常规>仅启用我的代码 (这是默认值)。
新的“介入”行为
启用JMC后,调试器将跟踪哪些代码是用户代码或系统/库代码。当进入具有PDB信息的函数时,执行将继续,直到到达另一个标记为用户代码的函数或当前函数完成其执行。这在实践中意味着,要获得代码,您不必花时间在无数行您不感兴趣的库代码上,或者,更常见的情况是,您可以停止处理遍布代码库的大量断点列表。
例如,在下面的代码片段中,如果没有JMC,如果您有足够的雄心壮志来“介入”,直到到达作为参数传递给标准库算法的谓词,那么您必须按F11(介入)140次!对于JMC,这只是命令调用的一个“步骤”。
STL算法 | |
![]() |
![]() |
另一个例子是进入Win32 API回调。如果没有JMC,调试器就无法判断某些用户代码最终将执行,因此它完全跳过win32api调用,而不进入用户定义的回调。JMC正确地将回调标识为用户代码,并相应地停止调试器。
Win32 API回调 | |
![]() |
![]() |
进入特定阶段
要显式地单步执行可能是非用户代码的调用,可以利用 “进入特定” 命令在编辑器的上下文菜单中可用。这允许您选择要单步执行的特定功能(无论是否为用户代码):
为其他第三方库配置“仅我的代码”
C++调试器认为非用户代码的模块和源文件的默认集在 默认.natjmc 文件位于 %%VSInstallDir%% Common7包DebuggerVisualizers 它还指定了WinSDK、CRT、STL和ATL/MFC等。
您可以通过以下方式自定义这组模块和源文件:
- 修改中的中心列表 %%VSInstallDir%%Common7PackagesDebuggerVisualizersdefault.natjmc 或
- 通过在 %%用户配置文件%%DocumentsVisual Studio 2017Visualizers 文件夹。
例如,要将所有Boost库视为非用户代码,可以在上面的文件夹中创建一个Boost.natjmc,其中包含以下内容。
<?xml version="1.0" encoding="utf-8"?><NonUserCode> <File Name="*oost*" /></NonUserCode>
不需要重新生成用户代码,这些更改就可以生效。在下一个调试会话中,单步执行使用Boost的代码将跳过Boost库代码,并且只有在调用堆栈上找到某些用户代码时才停止执行。
有关.natjmc文件格式的更多详细信息,请参见 C++只是我的代码文档页面 . 请注意,.natjmc格式还支持基于函数名将代码标记为非用户代码,但出于性能原因,我们不建议对经常调用的函数或大型函数组使用此功能(“函数”规则比“模块”或“文件”规则慢得多)。
第三方库 |
![]() |
在被子下面
如上所述,JMC功能仅对使用新的MSVC编译器开关/JMC编译的用户代码可用。对于调试配置中的MSBuild项目,默认情况下已启用此新开关。如果您使用的是不同的构建系统,那么您需要确保在项目的调试构建中手动添加off-by-default/JMC开关。
/JMC只支持与CRT链接的二进制文件。
要显式关闭JMC,可以使用/JMC-switch。
给我们你的反馈!
这次发布是第一次 Visual Studio 2017预览版 只支持我的代码步进。您的反馈是确保我们能够提供令人愉快的调试体验的关键部分。如有任何问题,请通过Twitter联系我们 @视觉 或通过电子邮件 visualcpp@microsoft.com . 如有任何问题或建议,请通过帮助>发送反馈> 报告问题 在IDE中。