可执行文件突然停止工作:静默退出,没有错误,什么都没有
Executable suddenly stopped working: silent exit, no errors, no nothing
我面临一个相当特殊的问题:我有一个 Qt C++ 应用程序,它曾经运行良好。现在,突然间我无法启动它了。没有错误被抛出,什么也没有。
更多信息:
- 当应用程序以 Visual Studio 2012 的调试模式启动时的最后一行输出:
The program '[4456] App.exe' has exited with code -1 (0xffffffff).
- 实际应用程序代码(= main() 中的第一行)从未被调用或至少没有触发断点,因此无法进行调试。
- 可执行进程在进程列表中出现几秒后又消失
- 具有最新 Windows 更新的 Win 7 x64。
- 问题同时出现在两台不同的机器上。
- 应用程序最初是使用 Qt 5.2.1 构建的。今天我测试切换到 Qt 5.4.1。但是果然没有变化。
- 未对源代码进行任何更改。该问题也适用于应用程序的现有版本。
- 运行 从我的角度来看,DependencyWalker 没有产生任何有趣的结果。
我完全没有想法。关于尝试或查看什么的任何指示?一个可执行文件怎么会突然完全停止工作而没有错误?
"Actual application code (= first line in main()) is never called. So debugging is not possible."
您可能有一些静态存储初始化失败,这是在调用 main()
之前应用的。
您在代码中使用任何相互依赖的单例吗?如果是这样,将它们合并为一个 单例(记住,不应超过 一个 单例)。
另请注意,对于这种情况,调试仍然是可能的,陷阱是,-对于我的回答中描述的这种情况-,main()
's bodies'第一行是在调试器中启动程序时,默认设置为第一个断点。
没有什么能阻止你设置断点,在启动代码之前命中的断点实际上达到 main()
。
关于您在评论中的澄清:
"I do use a few singletons ..."
如上所述,如果你真的确定你需要使用单例,那么就使用一个单例。
否则你可能会在静态存储初始化的未定义顺序中苦苦挣扎。
无论如何,如果静态存储数据相互依赖也没关系,在整个代码中为它提供一个单一访问点,以避免它因繁重而混乱耦合到各种实例。
与单个实例耦合,如果事实证明 singleton 不是一个,则可以更轻松地重构代码以配合接口。
我最终找到了这种行为的原因......有点。编码(例如我的单身人士)从来都不是问题(正如我所料,因为代码总是有效)。相反,外部库(SAP RFC SDK)引起了麻烦。
这个库依赖于 ICU Unicode 库和明显的特定版本。因为我不知道这个事实,所以我的应用程序目录中只有我当前使用的 Qt 版本需要的 ICU 库。到目前为止,SAP RFC SDK 的 ICU 库必须从标准 windows 路径加载。
最后,一些软件更改(Windows 更新、手动应用程序卸载等)一定已经删除了导致上述静默失败的那些库。只需将所需的 ICU 库版本 DLL 复制到我的应用程序文件夹中,即可解决问题。
我唯一不太确定的是,为什么在通过 DependencyWalker 跟踪加载的 DLL 时看不到它。
我面临一个相当特殊的问题:我有一个 Qt C++ 应用程序,它曾经运行良好。现在,突然间我无法启动它了。没有错误被抛出,什么也没有。
更多信息:
- 当应用程序以 Visual Studio 2012 的调试模式启动时的最后一行输出:
The program '[4456] App.exe' has exited with code -1 (0xffffffff).
- 实际应用程序代码(= main() 中的第一行)从未被调用或至少没有触发断点,因此无法进行调试。
- 可执行进程在进程列表中出现几秒后又消失
- 具有最新 Windows 更新的 Win 7 x64。
- 问题同时出现在两台不同的机器上。
- 应用程序最初是使用 Qt 5.2.1 构建的。今天我测试切换到 Qt 5.4.1。但是果然没有变化。
- 未对源代码进行任何更改。该问题也适用于应用程序的现有版本。
- 运行 从我的角度来看,DependencyWalker 没有产生任何有趣的结果。
我完全没有想法。关于尝试或查看什么的任何指示?一个可执行文件怎么会突然完全停止工作而没有错误?
"Actual application code (= first line in main()) is never called. So debugging is not possible."
您可能有一些静态存储初始化失败,这是在调用 main()
之前应用的。
您在代码中使用任何相互依赖的单例吗?如果是这样,将它们合并为一个 单例(记住,不应超过 一个 单例)。
另请注意,对于这种情况,调试仍然是可能的,陷阱是,-对于我的回答中描述的这种情况-,main()
's bodies'第一行是在调试器中启动程序时,默认设置为第一个断点。
没有什么能阻止你设置断点,在启动代码之前命中的断点实际上达到 main()
。
关于您在评论中的澄清:
"I do use a few singletons ..."
如上所述,如果你真的确定你需要使用单例,那么就使用一个单例。
否则你可能会在静态存储初始化的未定义顺序中苦苦挣扎。
无论如何,如果静态存储数据相互依赖也没关系,在整个代码中为它提供一个单一访问点,以避免它因繁重而混乱耦合到各种实例。
与单个实例耦合,如果事实证明 singleton 不是一个,则可以更轻松地重构代码以配合接口。
我最终找到了这种行为的原因......有点。编码(例如我的单身人士)从来都不是问题(正如我所料,因为代码总是有效)。相反,外部库(SAP RFC SDK)引起了麻烦。
这个库依赖于 ICU Unicode 库和明显的特定版本。因为我不知道这个事实,所以我的应用程序目录中只有我当前使用的 Qt 版本需要的 ICU 库。到目前为止,SAP RFC SDK 的 ICU 库必须从标准 windows 路径加载。
最后,一些软件更改(Windows 更新、手动应用程序卸载等)一定已经删除了导致上述静默失败的那些库。只需将所需的 ICU 库版本 DLL 复制到我的应用程序文件夹中,即可解决问题。
我唯一不太确定的是,为什么在通过 DependencyWalker 跟踪加载的 DLL 时看不到它。