程序在进入main之前崩溃时该怎么办?

时间:2017-08-25 06:46:33

标签: c++ windows visual-studio

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

我甚至不知道如何开始研究这个问题,代码已有几年历史了,从来没有遇到过这个问题。

知道该怎么做?

修改

正如建议的那样,我在WinMainCRTStartup中设置了断点,并将问题跟踪到exe_common.inl中的第224行函数__scrt_common_main_seh():

if(_initterm_e(__ xi_a,__ xi_z)!= 0)  返回255;

该行失败,因此函数返回255并且我的主函数永远不会被调用。有什么进一步的想法吗?

3 个答案:

答案 0 :(得分:2)

假设调试器有捕获问题,我知道只有可能工作。 如何通过terminate设置自己的set_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_;

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

我最近在VS 15.9.4上遇到了同一崩溃,它似乎与setargv.obj有关,后者扩展了命令行通配符。它影响了x64版本的构建,但不影响调试或x86的构建,并且取决于参数格式。我的程序仅使用标准C ++,没有外部库。除了几个POD之外,它没有全局或静态变量。

我有一个本地目录solarcaptures,其长度为0的文件名为out_0001_21605508221437,没有后缀。运行collat​​epackets exe会扩展命令行参数:

collatepackets solarcaptures\*

但是,将命令行更改为以下内容会导致在x64 Release版本的相同初始化代码中发生访问冲突。

collatepackets solarcaptures\out*

更新:我使用printf列出了一个主程序,并编写了一个最小程序。它在x64 Release版本上崩溃。在VS2017全新安装的两个最新Windows 10上对其进行测试。非常可重复,但对要扩展的特定名称敏感。缩短目录名称有时可以使其工作。