C++ 进入main前访问违规读取位置

C++ 进入main前访问违规读取位置,c++,visual-studio-2015,heap-corruption,mixed-code,C++,Visual Studio 2015,Heap Corruption,Mixed Code,从Visual Studio 2012升级到Visual Studio 2015后,我的项目在到达主函数之前就出现堆损坏和访问冲突错误。根本没有我可以调试的代码。我检查了静态变量和任何可以在堆栈上创建的变量,但似乎没有。我试图用空的主功能启动程序: int main(){return 0;}; 但我仍然得到访问冲突错误。该程序是一个GUI表单,包含混合的C++/CLI代码。我确保使用VS2015从源代码重建了第三方库(curl),并使用了正确的DLL。不知道这些错误是从哪里来的-以前一切都很好

从Visual Studio 2012升级到Visual Studio 2015后,我的项目在到达主函数之前就出现堆损坏和访问冲突错误。根本没有我可以调试的代码。我检查了静态变量和任何可以在堆栈上创建的变量,但似乎没有。我试图用空的主功能启动程序:

int main(){return 0;};
但我仍然得到访问冲突错误。该程序是一个GUI表单,包含混合的C++/CLI代码。我确保使用VS2015从源代码重建了第三方库(curl),并使用了正确的DLL。不知道这些错误是从哪里来的-以前一切都很好。如何修复/调试它?我在谷歌上搜索了很多,甚至试着运行gflags,但调试器在任何人类可读的代码上都不会停止。错误内容如下:

在MyProgramName.exe中的0x5A4C7988(verifier.dll)处引发异常:0xC0000005:访问冲突读取位置0xA46FEC13

编辑1: verifier.dll与错误无关。原来这个库是在我将图像文件添加到gflags.exe试图调试程序时加载的。放弃这些更改后,我返回到原始错误消息,该消息是由ntdll.dll引发的堆损坏

编辑2: 我通过删除所有的.h文件和.cpp文件将代码精简到最低限度,直到错误消失。这是一种非常低效的调试方法,但由于我不知道还有什么更好的方法,所以我还是这样做了

#include "MyGUI.h"
#include <boost/date_time/posix_time/posix_time.hpp>

[STAThread]
void main(array<String^>^ args) {
    Application::EnableVisualStyles();
    Application::SetCompatibleTextRenderingDefault(false);
    Application::Run(gcnew MyProject::MyGUI);
}
编译器指令已足够。根据,

纳秒分辨率选项为每个ptime使用96位底层存储,而微秒分辨率为每个ptime使用64位

后一句话以及x64位库工作良好的事实使我认为该库的32位实现是错误的

对于那些可能觉得它有用的人来说,这就是原因。至于我最初的问题如何调试这样一个崩溃当堆甚至在到达入口点之前就损坏了(因此没有任何源代码或调试信息可用)而不浪费7个小时剥离项目直到只剩下一行时-我保留这个问题

如果有人能指出一种更好的方法来发现此类错误,这将是非常有启发性的

编辑3: 显然,这还没有结束。在修复boost库并恢复到完整代码后,我再次遇到了错误。问题是由于在GUI windows窗体方法回调中使用静态变量引起的:

System::Void comboBoxStart_SelectionChangeCommitted(System::Object^  sender,
                                                    System::EventArgs^  e) {

    static wstring LastChoice; //This line is enough to reproduce the crash

}

有人能解释为什么这会导致访问违规读取位置吗?类似的症状在文章中有描述。

在加载
main
之前,可执行文件将加载相关库并执行它们自己的“
main
”。这比这要复杂一点,但需要理解的重要一点是,代码首先在这些库中执行。如果存在错误,它将崩溃


您的错误消息提到,
verifier.dll
是问题的根源。您应该首先调查该DLL。你自己造的吗?它是否具有运行所需的所有依赖项?

访问冲突是由于在托管代码中使用静态变量造成的。我在Windows窗体GUI回调(托管代码)中使用了一个静态字符串WSKY类型(原生C++类型!)。我的猜测是,程序试图在托管代码初始化结束之前初始化变量,甚至在到达程序入口点之前就导致了错误


从托管代码中删除所有静态变量后,问题就消失了。

我认为您需要在main()中返回一个值@smttsp:这是隐含的。谢谢smttsp,这只是一个输入错误。我现在已经纠正了它,以明确这与访问冲突无关。不,我不知道什么是verifier.dll库。我唯一拥有的依赖库是从源代码重建的CURL。我感觉这个错误发生在托管代码被“初始化”并且应用程序转移到非托管代码之后?这是我在谷歌上搜索到的关于这个问题的最好的猜测……你有没有试过为了测试而删除curl?它在curl不加载时运行吗?如果代码中有错误,我会很快调试它。关键是它是另一个库,我不知道它来自哪里,因为它甚至没有到达main,也没有被我链接。我不记得确切的后果,但我记得让纯C库与C一起工作是一件痛苦的事。您是否考虑过使用libcurl的C#端口?还有一些项目设置要在c中调试本机代码,您启用了吗?
BOOST_DATE_TIME_NO_LIB
System::Void comboBoxStart_SelectionChangeCommitted(System::Object^  sender,
                                                    System::EventArgs^  e) {

    static wstring LastChoice; //This line is enough to reproduce the crash

}