Visual Studio: 在 main() 函数调用之前调试

Visual Studio: Debug before main() function call

我遇到了一个问题,我的应用程序在执行任何操作之前就无法通过调试断言 (_CrtIsValidHeapPointer)。我知道这一点是因为我在 main 函数的第一条语句上添加了一个断点,并且在到达断点之前断言失败。

有没有办法以某种方式 "step through" 在调用主函数之前发生的所有事情?静态成员初始化等

我应该注意到我的程序是用 C++/CLI 编写的。我最近升级到 VS2015,目标是 v140 工具集。我正在使用的 C++ 库(ImageMagick、libsquish 和我自己的 C++ 库之一)已经过单独测试,我没有收到这些库的断言失败,所以它必须是我的主要应用程序。

自从我从 VS2013 升级后,我没有更改任何代码,所以我对发生的事情有点困惑。

编辑: 这是调用堆栈。这是我点击"Retry"后断言失败window。然后我会抛出许多其他异常,但每次我 运行 程序时它们都不一样。

>   ucrtbased.dll!527a6853()    
[Frames below may be incorrect and/or missing, no symbols loaded for ucrtbased.dll] 
ucrtbased.dll!527a7130()    
ucrtbased.dll!527a69cb()    
ucrtbased.dll!527c8116()    
ucrtbased.dll!527c7eb3()    
ucrtbased.dll!527c7fb3()    
ucrtbased.dll!527c84b0()    
PathCreator.exe!_onexit(int (void)* const function)  Line 268 + 0xe bytes   C++
PathCreator.exe!atexit(void (void)* const function)  Line 276 + 0x9 bytes   C++
PathCreator.exe!std::`dynamic initializer for '_Fac_tidy_reg''()  Line 65 + 0xd bytes   C++
[External Code] 
mscoreei.dll!7401cd87()     
mscoree.dll!741fdd05()  
kernel32.dll!76c33744()     
ntdll.dll!7720a064()    
ntdll.dll!7720a02f()    

您必须调试 C 运行时初始化代码。这样做并不直观,因为调试器会努力避免它并让您进入 main() 入口点。但仍有可能,请使用调试 > 新断点 > 函数断点。

为函数名称输入 _initterm,语言 = C。

按F5,断点就会命中。您应该看到 C 运行时源代码。您现在可以一个接一个地单步执行程序的初始化函数,每次调用 (**it)() 都会执行一个。


这正是您所要求的。但不太可能是你真正想要的。 您的 代码产生此错误的几率非常低。更有可能是这些库之一导致了这个问题。它们很可能是针对 C 运行时库的 另一个 版本构建的。因此有自己的 _initterm() 函数。

在一个进程中拥有多个 C 运行时库副本通常是非常不健康的。并且极有可能产生堆损坏。如果您无法从堆栈跟踪中找到它(请务必将调试器类型从自动更改为混合,始终 post SO 问题中的堆栈跟踪)那么接下来您应该 强烈 考虑使用您使用的 VS 版本重建这些库。