2017-08-25 394 views
2

我有一个很奇怪的问题。我们的公司应用程序是一个用C++编写的桌面应用程序,并使用Visual Studio 2017进行编译。在过去的几个星期里,有时应用程序在进入main之前会崩溃。我知道这一点,因为我在main的第一行放置了断点,并且它永远不会被调用。碰撞不会很快发生,所以我有时间在诊断工具中全部按下休息。但是我只收到一条消息'你的应用程序已进入休息状态,但没有代码显示,因为所有线程都在执行外部代码(通常是系统或框架代码)“。有时清理所有东西并重建会使代码正常工作,但有时候不会。在进入main之前程序崩溃时该怎么办?

我甚至不知道如何开始调查此问题,代码已有几年的历史,并且从未遇到过这个问题。

不知道该怎么办?

编辑

至于建议,我在WinMainCRTStartup设置断点,我跟踪这个问题到线224功能__scrt_common_main_seh()在exe_common.inl:

如果(_initterm_e(__ xi_a,__xi_z)= 0) return 255;

该行失败,所以该函数返回255,我的主永远不会被调用。还有什么想法?

+2

*任何*崩溃通常要做的就是在调试器中捕捉它,并找到它发生的代码的位置。如果它不是源自你的代码,那么你应该在'main'函数中寻找大数组,因为Windows每个进程只有一个默认的一兆字节的堆栈,并且在'main'之前似乎崩溃了,通常是你有一个符号由于存在多个或大型局部变量(局部变量,包括数组),导致堆栈溢出通常存储在堆栈中。 –

+1

如果你不*有任何大型数组,那么调试器应该已经捕捉到了崩溃,并且很可能指出了一些全局变量的初始化。 –

+1

我会检查的一个选项是一些缺失的依赖关系。如果您拥有所有依赖的dll验证工作目录是否设置正确 – Dusteh

回答

0

我终于让我的程序再次运行。原因是该程序现在使用Visual Studio 2017进行编译,但是一些与我的程序静态链接的库是使用以前的Visual Studio构建的,在使用Visual Studio 2017重新编译它们之后,我的程序运行良好。

因此,如果程序在退出之前崩溃,则要检查是否确保使用相同的编译器和使用相同的编译器开关构建所有库。

2

假设调试器在捕获方面有问题,我有一个想法,只有可能工作。 如何通过set_terminate设置您自己的terminate功能? http://www.cplusplus.com/reference/exception/set_terminate/ 你可以在静态全局变量的构造函数中完成它,它可能在崩溃你的软件之前被调用。不确定的初始化静态变量的顺序是不确定的。 尝试在其中设置断点。

int main() 
{ 
    throw 0; 
    return 0; 
} 

struct reterminator 
{ 
    static void myterminate() { 
     std::cerr << "terminate handler called\n"; 
     abort(); // forces abnormal termination 
    } 

    reterminator() 
    { 
     std::set_terminate(myterminate); 
    } 
} static reterminator_; 
相关问题