Visual Studio - 条件断点和禁用断点对运行时的影响
在花了一些时间想知道为什么我的应用程序在附加调试器的情况下运行特定场景非常缓慢之后,我发现这是由于有一个条件断点(其条件从未得到满足)。这似乎是合理的,因为 CPU 会发出断点信号,而 VS 需要在允许继续执行之前评估条件。这些转变必定代价高昂。
我假设未执行的代码路径中的断点不会对运行时产生影响。
所以我的问题是双重的:
- 是否有任何资源可以量化与条件断点相关的成本,如果有的话,可以做些什么来减少运行时评估成本?
- “禁用”断点是否会产生任何相关成本?我所说的禁用是指 VS 在装订线中显示带有空心圆的断点标记。
当然,如果我上面提到的任何内容没有意义,那么请为我指出正确的方向。
After spending a little time wondering why my app was running a particular scenario very slowly with the debugger attached, I discovered that this was due to having a conditional breakpoint (whose condition was never being met). This seems reasonable, as the CPU would signal the breakpoint and VS would need to evaluate the condition before allowing execution to continue. These transitions must be costly.
I assume that a breakpoint in a code path that is not executed has no runtime impact.
So my question is twofold:
- Are there any resources that can quantify the cost associated with conditional breakpoints, and if so is there anything one can do to reduce their runtime evaluation cost?
- Is there any cost associated with a 'disabled' breakpoint? By disabled I mean that VS displays the breakpoint marker in the gutter with a hollow circle.
Of course if anything I've mentioned above doesn't make sense, then please point me in the right direction.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
很难量化条件断点的成本。条件断点中的表达式的计算使用完全相同的语义,就像您将其输入到监视或立即窗口中一样。这种性质的表达式实际上并不在客户端程序中执行,而是由特定于语言的表达式求值器处理。以有意义的方式描述这些类型的评估实际上是不可能的。
不过,我可以列出一些已知在调试窗口中较慢的事情 eval
至于禁用的断点,不,它们不会影响应用程序的运行。
It's hard to quantify the cost of a conditional breakpoint. The expression in a conditional breakpoint is evaluated using the exact same semantics as if you had typed it into the watch or immediate window. Expressions of this nature are not actually executed in the client program but instead handled by the language specific expression evaluator. It's not really possible to profile these types of evaluations in a meaningful way.
However I can list a few things that are known to be slower in a debug window eval
As for disabled breakpoints, no they do not affect the running of the application.
需要注意的一件事(我通过艰难的方式学到了这一点)是确保在将变量与值进行比较时放置 == 而不是单个 =
断点编辑器不会警告您,但是当评估断点时,变量被改变了!我花了一些时间来调试我的代码!
另外,如果我真的需要条件断点来调试代码;我将条件添加到代码中,然后添加类似 string stop = "here"; 的内容并在那里放置一个正常的断点 - 我发现代码运行得更快。
One thing to watch out for (which I learned the hard way) is to make sure you put == when comparing a variable to a value and not the single =
The breakpoint editor doesn't warn you but when the breakpoint is evaluated, the variable is altered! Took me a while to debug my code with that one!
Also, if I really need the conditional breakpoint to bebug code; I add the condition to the the code, then add something like string stop = "here"; and put a normal breakpoint there - I find the code runs faster then.
我在某处读到,这些断点有硬件支持,因此使用少于 x 个某种条件断点基本上是免费的,但除此之外,它需要使用更多的软件。 (OTOH,那是针对本机应用程序的,不确定这些新奇的 JIT 事物。)
禁用的断点应该会影响所有事情,它们只是在 IDE 中占用一些内存和 GUI 资源。
I read somwhere that there is hardware support for these breakpoints, so that using fewer than x conditional breakpoints of a certain kind is essentially free, but above that, it needs to use more software. (OTOH, that was for native apps, not sure about these newfangled JIT things.)
Disabled breakpoints should take affect things at all, they just occopy some memory and GUI resources in IDE.
我还注意到条件断点的成本很高,并且得出了与您相同的结论。我无法想象禁用断点会导致速度减慢的任何原因,因为我希望它只是编辑器的东西,是在需要时打开断点的快捷方式。
当我遇到像你这样的情况时,我所做的就是创建一个断言宏。 (您可以使用 Visual Studio 提供的 assert 宏,但我不喜欢)。让您的宏检查所需的条件,然后调用 DebugBreak< /a> 如果失败。在应用程序的发布或非检查构建中,将断言评估为空,因此您的代码不会受到影响。
一个简单的断言宏可以如下所示:
并这样调用它:
您可以在 DebugBreak 之前在失败中放入更多代码(例如使用 #x 打印失败的条件,和/或使用 ____FILE____ 和 ____LINE____ 打印出失败的条件,这样您就可以双击该消息)。您可以使用 OutputDebugString 甚至检查调试器是否附加了 IsDebuggerPresent 进一步定制您的断言。我也喜欢使用 &&字符串格式以提供有关特定断言的更多信息。
使用assert时有几点需要注意。首先,不要将任何必须在宏中运行的代码放入宏中,因为它将在非调试版本中被删除。出于同样的原因,不要放入有副作用的代码。此外,您不希望在未附加调试器时调用 DebugBreak(),因为它本质上会引发异常,如果未捕获该异常,则会终止应用程序。
I have also noticed that conditional breakpoints are expensive and came to the same conclusion as you. I can't imagine any reason that a disabled breakpoint would cause any slowdown since I would expect it to be an editor only thing, a shortcut for turning on a breakpoint should you need it.
What I do when I am in a situation like yours is make an assert macro. (you can use the assert macro that visual studio provides, but I dont like it). Have your macro check the condition you want and then call DebugBreak if it fails. In the realease, or non-checked build of your application, have assert evaluate to nothing, so your code is not impacted.
A simple assert macro can look like:
and call it like:
You can put more code in the failure before DebugBreak (like printing out the condition that failed with #x, and/or the line/file number with ____FILE____ and ____LINE____ so you can double click on the message). You can write messages to the debug log with OutputDebugString and even check to see if a debugger is attached with IsDebuggerPresent to tailor your assert even more. I also like to use the && string format to give a bit more information on the particular assert.
There are a few things to be careful of when using assert. First, do not put any code that MUST be run in the macro, since it will be stripped in a non debug build. For the same reasons, don't put in code that has side effects. Also, you do not want to call DebugBreak() when a debugger is not attached because it essentially throws an exception, which if not caught, will terminate the application.
尝试在你的
代码来测试性能。 EG
不,不完全相同,但足够接近。
否 - 禁用的断点不是
存在于正在执行的程序中。
它只是存储在 VS 元数据中
为了您的方便。
Try putting the breakpoint in your
code to test the performance. E.G.
No, not exactly the same but close enough.
No - a disabled breakpoint is not
present in the executing program.
It is just stored in the VS metadata
for your convenience.