VS2012:在没有更多信息的情况下,调试器启动时在ntdll.dll中设置断点

12

有时我在使用VS2012以Debug模式启动/调试应用程序时会收到一个对话框:

<blahblah.exe>已触发断点。

该对话框没有提供其他信息,因此我按下“中断”按钮以查看发生了什么。但是,接下来我遇到了"wntdll.pdb未加载"的错误,并且没有其他关于问题的信息。调用堆栈指向ntdll.dll,而且在此时似乎我的应用程序尚未开始执行。

在此处选择继续将允许应用程序/调试器像往常一样继续运行。

这种情况非常频繁(大约10次中有7次)。我正在运行Windows 8(64位)和带有更新1的Visual Studio 2012。

以前我使用Windows 7(64位)和VS2010,从未遇到过这个问题。该项目已从创建它的版本(2010)进行了升级,因此可能是问题的一部分。

有人遇到过这个问题吗?我不知道从哪里开始寻找原因。虽然我正在运行64位的Windows,但我应该提到我正在构建32位的应用程序。

更新:启用Microsoft符号服务器后,调用堆栈如下所示:

>   ntdll.dll!_LdrpDoDebuggerBreak@0()  Unknown
    ntdll.dll!_LdrpInitializeProcess@8()    Unknown
    ntdll.dll!__LdrpInitialize@8()  Unknown
    ntdll.dll!_LdrpInitialize@8()   Unknown
    ntdll.dll!_LdrInitializeThunk@8()   Unknown

我还应该补充一下,以防万一,我在代码中绝对没有手动设置任何断点


启用Microsoft符号服务器,以便获取所有Windows函数的符号。您将获得一个相当注释良好的调用堆栈。如果这并没有帮助您,请在您的问题中发布它。 - Hans Passant
尽管我尝试了,但我没有意识到我需要先打开设置并选择“加载所有符号”。 - tacospice
当出现这个问题时,您的计算机上是否安装了>=2个版本的VS? - ManuelH
4个回答

5
这个烦人的问题源于Visual Studio中的一个错误:
引起问题的原因是我们没有正确地处理来自不同进程的多个加载器断点事件。操作系统在进程启动但在任何执行之前触发加载器断点,以便调试器可以实例化断点并采取其他操作。通常情况下,我们会成功忽略这些(至少在单次启动的情况下)。您可以通过在“工具”->“选项”->“调试器”中禁用“一个进程中断时中断所有进程”复选框来解决此问题。还要注意,这不是致命错误。我们只是在内部断点处停止,您可以再次按F5继续。
这是一种竞争条件,所以对我们来说很难追踪,在VS中的多重启动使用率相当低,因此我不会修复这个问题,假设上述解决方法足以使您解除阻塞,如果我们看到更多客户的报告,我们将重新考虑这个问题。这听起来对您合理吗?
再次感谢您的反馈。
Marc Paine Visual Studio Debugger Engineering Manager 来源:Microsoft Connect 我遵循了在Visual Studio调试器设置中禁用“一个进程中断时中断所有进程”复选框的建议,并且目前这个问题已经“解决”了。
也许如果我们能让更多人报告此错误/烦恼,微软最终会像他们建议的那样修复它。

这个 bug 已经困扰我相当长的一段时间了,但是只有最近在深入搜索后才发现了关于它的 Microsoft Connect 文章。我很高兴现在存在这个解决方法。 - ManuelH
我开始随机地在无处的中间遇到这个令人讨厌的断点,原因不明,谷歌引导我找到了这个答复。禁用那个复选框有所帮助。顺便说一句,MS Connect链接现在已经失效了。 - Pavel P
1
在VS2019中仍然存在。我们正在生成多个进程来组成一个“应用程序”。为了调试这个问题,我们必须安装“Microsoft Child Process Debugging Power Tool”。这是一个非常有用的扩展,但似乎每次运行解决方案时都会引起这个问题,并且停止的次数从零次(不频繁)到5次(频繁)或更多(不频繁)。很容易走开去喝咖啡,回来时它还没有完成 :) - bmahf

3
如果你在调试器下运行应用程序,进程一开始就会自动断点。这个断点可以让你在进程开始执行之前设置更多的断点。如果你不喜欢它,通常调试器中有一个选项可以忽略初始默认断点。例如,在 cdb 中,选项是-g

出于好奇,那么为什么它只在10个案例中的7个中出现错误?难道它不应该每次都出错吗? - OregonGhost
@OregonGhost 我对此无法解释。但你所触发的断点是默认的初始断点。你可以配置是否应该遵守初始断点。 - Raymond Chen
这对我来说更像是一个竞争问题。正如我在评论中所述,我的具有多个进程的应用程序可能会在启动时从零次到5次或更多次触发此断点。该应用程序由大约15个进程组成。 - bmahf

0

我刚刚发现自己遇到了类似的问题,不过我的调用栈如下:

ntdll.dll!LdrpDoDebuggerBreak()
ntdll.dll!LdrpInitializeProcess()
ntdll.dll!_LdrpInitialize() 
ntdll.dll!LdrInitializeThunk()

在我的情况下,我的Visual Studio解决方案有几个项目,其中三个项目通过解决方案的“多启动项目”设置设置为启动(和调试)。
两个启动项目是(非托管)C++,其中一个是C#。我能够通过打开C#项目的项目属性并启用“本机代码调试”来摆脱此启动断点。

"Enable native code debugging" checkbox

编辑:显然这并没有完全解决我的问题,只是大大减少了它发生的频率。不过,我认为同样的一般解决方案仍然可以修复它。

此解决方案中的另一个项目只是一个预构建的二进制文件,通过手动指定该二进制文件作为项目的TargetPath来启动。

在项目的Debugging属性页中将Debugger Type更改为Native Only似乎也有所帮助。

"Native Only" Debugger type

所以,改变这两个似乎对我来说实际上解决了问题。


-1

查看是否已经开启了在第一次异常时进入调试器的选项。

您可以在“调试/异常…”下找到此选项。查看是否有任何框被选中。(至少在旧版的VS中是这个菜单位置 - 我目前没有VS 2012) 如果启用了此选项,即使应用程序正确处理了异常,调试器也会在抛出异常时中断。如果禁用,则调试器仅在未处理异常时中断。如果已检查任何异常,请尝试取消选中它们并查看是否仍然存在此问题。


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