Visual Studio调试器跳过断点

15

我的 Visual Studio 2008 IDE 在调试单元测试时表现非常奇怪:我设置了一个断点,当我命中它并尝试使用 F10 进行步进时,测试就会结束。如果我在被测试方法内的每一行上设置断点,我最终会停留在其中一个随机的位置,而不是下一行的位置。我已经在干净的系统重新启动后清理和重建了解决方案,但这种行为仍然存在。还有其他人遇到过这种情况吗?是否有结论得出。

此测试仅使用主执行线程(没有创建额外的线程)。


2
你只有在从单元测试中调试时才遇到这个问题吗?你是否也尝试从控制台应用程序运行相同的代码?你使用哪个测试框架? - jeroenh
调试版本?关闭优化?正确的符号文件?可能有另一个线程在同一个函数内执行吗?堆栈损坏?是否有模态 UI 弹出(特别是断言失败),可能正在另一个线程中发送消息? - Adrian McCarthy
@jeroenh: 在非单元测试条件下,我的项目出现了一些奇怪的问题。这是服务代码,调试构建是控制台应用程序。我正在使用Visual Studio内置的单元测试框架。 - My Other Me
@Adrian:调试版本已确认。关闭优化已确认。如何确认符号文件?在单元测试框架中,函数内只有一个线程。如何检查堆栈损坏?目前仅为控制台应用程序进行调试,没有用户界面。 - My Other Me
你检查过测试结果文件夹是否也被清空了吗?要将服务作为控制台应用程序运行,你可以做两件事:1)将项目类型更改为控制台,2)在主方法中检查 Environment.IsInteractive(或类似的内容),并相应地调用 ServiceBase.Run... - Charles Prakash Dasari
13个回答

27

发布了一个VS2008 SP1热补丁,解决了一些调试问题。KB文章在这里,热补丁下载在这里


更新:热补丁下载位置已停用,不知道是否有替代下载位置。如果您发现了,请编辑此帖子。


2
这绝对是一个已知的错误。这个答案需要被点赞。 - Chris Stavropoulos

10

如果你调试的是发布版本(因为行被优化了),就会出现这种行为。

如果我不小心在调试其他地方的旧exe文件(由项目配置设置),而不是最近构建的文件,也曾经发生过这种情况;^)


生成的是调试版本。我在发布版本和调试版本之间切换,并清理并重新生成了所有 bin 文件夹。现在我该如何确定将要运行哪个可执行文件。 - My Other Me
项目->项目属性->调试选项卡...但如果您从未更改/使用过它,它肯定不会更改为另一个exe。 - Toad

4
我在VS 2003上遇到了类似的问题。结果发现我使用了错误的符号,因此无法正确地绑定源代码。
请确保以下事项:
1. 使用Debug版本构建(或者关闭任何类型的优化); 2. 构建输出路径正确(即“项目属性\链接器\输出文件”与您正在调试的exe匹配); 3. 不要在变量声明处放置断点: 即,如果您在“int some_variable;”上设置断点,将永远不会被触发,而是会命中其后面的第一个位置,在那里定义/初始化一些东西或调用某些方法; 4. 您不能使用F10步进(执行下一条语句),但可以使用F11步进(执行下一条语句并跟踪执行进入方法调用); 5. 确保没有任何断点过滤器(例如命中计数或条件)。
提示:尝试在两种方法中都放置DebugBreak()函数(除非此代码在某个循环内执行,否则可能会令人沮丧)。这应该会在执行到这些函数时终止您的进程(以便您可以从特定位置继续进行调试)。

#3 是解决了我的问题。还有,它不会碰到花括号——细节问题... - Jon Peterson
只是为了更正我的先前评论 - 当您尝试在空测试的开放大括号上中断时,它不会中断。 - Jon Peterson
关于#3:如果您的项目的高级编译器设置->“生成调试信息”设置为pdb-only,则在调试时断点将从变量声明中移开,并在此后放置在代码的相关位置。如果设置为“Full”或“None”,则断点不会被移动,因此您永远无法触发它。 - Frinavale
Debugger.Break()让Visual Studio 2013进入我的测试方法。但是,一旦我触发了ShimsContext.Create()语句,VS就开始寻找ObjectCloneHelper.cs文件——我不知道那个文件是什么或者它应该来自哪里... - Zarepheth

3

当您有多个线程运行时,也会出现此行为。


2

你是否将断点放在生成类的一部分代码中?

我曾在服务引用的客户端遇到过这个问题。生成的类是带有部分类的。

    [System.Diagnostics.DebuggerStepThroughAttribute()]

应用属性。即使我的断点在不同的文件中,但仍然属于属性类的一部分,断点也会被跳过。

我从生成的 Reference.cs 文件中删除了该属性,调试器就像我预期的那样工作。

当然,这不是一个永久性的解决方案,因为如果 Reference.cs 文件重新生成,属性将会重新出现。


2
即使在调试版本中,编译器优化也可能会解释这种行为。在项目属性下的“构建”中,验证复选框“优化代码”是否关闭。我曾看到某些从.Net 1.1升级的项目默认开启此选项。

解决方案是一堆3.5项目。我已经检查了所有项目,并确认优化已关闭。其中一些项目包括一些1.1程序集以支持旧版。遗留组件的构建类型是否会影响我的解决方案? - My Other Me

0

进入项目->属性并取消选中 "优化代码"

如果您看到像DataSet ds = new DataSet();这样的代码在调试器上被触发,但像string Test = "Test";这样的代码被跳过,则应采取此步骤。


0
我在Visual Studio Community 2013中遇到了这个问题。这种行为似乎是设计上的。当运行测试时,执行不会停在断点处。如果你想要执行停在断点处,选择TEST-->Debug而不是TEST-->Run。

0

也许回复有点晚了,我在VS2012中遇到了同样的问题。要解决这个问题,请检查菜单Test>TestSettings>“LocalTestRun.TestRunConfig”是否被选中,如果被选中,请取消选中它,这样就不会跳过代码行了。对于Vs2008也可能适用。


0
这可能只是测试框架没有加载您当前正在工作的相同程序集的简单情况。我在 NUnit 中偶尔遇到过这种情况,它使用被测试程序集的副本进行工作;偶尔会停止复制最新版本。您的断点是否带有“未加载符号”指示器?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接