Visual Studio“14”中C++调试改进

在 Visual Studio 2015 我们已经介绍了C++调试经验的两个改进,以解决我们从您那里听到的痛点。提高了启动应用程序时的启动性能(F5),并减少了从监视或即时窗口死锁调用函数的机会。

null

提高了F5的启动性能

当进程由本机调试器启动时, Windows使用调试堆而不是普通堆来分配内存 . 调试堆具有诊断帮助,例如分配/取消分配sentinel值和其他诊断功能,以帮助诊断与堆相关的错误。然而,在分配内存时,这种额外的检查是以性能为代价的,并且 C运行时(CRT)有自己的堆检查功能 因此,如果您的程序正在使用CRTs函数来分配内存(例如malloc),那么就不太可能需要操作系统的。

因此,为了提高VisualStudio 2015在启动C++应用程序时的性能,在VisualStudio中禁用操作系统的调试堆。如果您真的对使用操作系统的支持来调试堆相关的问题感兴趣,那么您可以打开该功能,而不是我们在每次调试时默认为每个人打开它。

要启用操作系统的调试堆,可以通过以下两种方式之一重写此行为。

  1. 要对每个项目进行修改,请打开“项目属性”页,选择“配置属性->调试”并更改环境属性(值为1将启用该属性,值为0将禁用该属性)。 clip_image002
  2. 要为VisualStudio中的每个项目进行修改,请转到“工具”->“选项”->“调试”,并选中“启用Windows调试堆分配器(仅限本机)”选项。请注意,如果在项目中设置了上一点中提到的u NO u DEBUG u HEAP环境变量,它将始终覆盖此全局设置。 clip_image004

在计算函数时减少死锁的机会

我们所做的第二个改进是减少从Watch调用函数或立即窗口死锁的风险。

如果你 需要通过在调试器中停止时调用函数来测试或调试功能如果进程有多个线程,则可能导致函数死锁。即使代码没有显式地获取锁,如果函数分配任何内存,它也会在分配期间隐式地获取锁。这意味着,当您在调试器中停止时,如果进程中的任何其他线程正处于分配过程中,那么它现在将在持有锁时挂起。通常情况下,当在调试器中对某个函数求值时,该函数是进程中运行的唯一线程,因此如果它需要另一个线程按顺序释放锁,则会死锁 完成。

如果发生死锁,调试会话将结束。如果从“监视”窗口进行调用,则调试器将中止函数调用(如果需要10秒以上才能完成)。一旦一个函数被中止,但是,您的程序是一个未知的状态,所以可能需要重新启动。要查看此操作,请下载附带的示例并在注释指示的位置设置断点。在Visual Studio 2012或Visual Studio 2013中打开应用程序,然后单击断点

clip_image006

类型 函数(1) 在监视窗口。您将看到鼠标旋转,然后出现超时。

clip_image008

如果在即时窗口中键入FuncEvalFunction(1),调试器将等待函数完成,而不是超时。这是因为从立即窗口调用函数时可能会遇到断点,因此必须停止调试才能解决挂起问题。

通过visualstudio“14”来改善这种情况,调试器使用 窗口的等待链遍历 用于确定所计算的函数是否在等待另一个线程释放锁时处于死锁状态的功能。如果调试器检测到线程死锁,它将允许进程中的所有线程运行(调用 螺纹打滑 )直到求值函数完成。需要注意的是,在正在滑动的线程中,通常会导致调试器停止的事件(异常和断点)会被忽略。这意味着,如果对导致线程打滑的函数求值,并且在打滑的线程上发生异常或断点,则调试器不会通知您,事件将被忽略。希望发生这种情况的几率很低,而且应该只发生在功能评估无法完成的情况下。

在visualstudio的“监视”窗口中尝试上述评估 2015导致功能完成(您可以 使用附加的项目自己尝试这个 ).

clip_image010

显然,这只会在允许不同线程运行解决问题的情况下解决死锁,而在其他情况下(例如,当函数等待从未发送的通知时)则无法避免死锁。

结论

试用这些新功能 在Visual Studio 2015中 让我们知道你对它们的看法,或者你调试C++代码的任何其他问题。您可以通过VisualStudio中的“发送微笑”功能或我们的网站在下面提供反馈 MSDN论坛 .

此外,还检查了我们对所有语言(包括C++)调试经验的其他改进。 VisualStudioALM博客上的Diagnostics频道 包括 改进的断点经验 性能提示 .

死锁示例.zip

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享