抛出异常时应用程序崩溃
Application crashes when throwing an exception
在我正在编写的应用程序中,我使用异常来处理大多数错误。我还没有定义自己的异常类,我只是做了下面的事情:
namespace Mage {
typedef std::exception Exception;
}
这样,当我以后定义自己的类型时,我就不必修改所有的代码,因为我应该使用相同的接口。也就是说,任何异常都会使我的应用程序崩溃。考虑到上面的定义,为什么会崩溃呢?void Mage::Root::initialize(Mage::String& p_log) {
// initialize GLFW and GLEW.
if (!glfwInit()) {
throw new Mage::Exception("failed to initialize OpenGL");
return;
} else m_GLFWInitialized = true;
无论我删除或保留'new',它仍然会崩溃。我错过什么了吗?我已经查了教程,但那些并没有让我更聪明。
我也在这里捕获了错误:
try {
MAGE_ROOT.initialize(Mage::String("Mage.log"));
} catch (Mage::Exception& e) {
std::cerr << e.what() << std::endl;
}
我得到的崩溃是:
Debug Error!
Program: ...sual Studio 2010ProjectMage3DBinariesDebugTest.exe
R6010
- abort() has been called
(Press Retry to debug application)
问题是你没有捕捉到异常。
我不知道你必须从注释中捕获异常
是的,你必须。如果没有捕获抛出的异常,则会调用std::terminate()
。这是预期的行为:异常的存在是为了防止程序员忘记错误处理。
话虽如此,我建议:
- 按值抛出;
- 参考捕集
void foo()
{
// ...
throw std::logic_error("Error!");
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Throw by value (std::logic_error derives from std::exception)
// ...
}
void bar()
{
try
{
// ...
foo();
// ...
}
catch (std::exception& e)
^^^^^^^^^^^^^^^
// Catch by reference
{
std::cout << e.what(); // For instance...
}
}
更新:
关于你发布的代码片段,你正在抛出指针并通过引用捕获。处理程序不匹配。由于没有其他匹配的处理程序,因此将调用std::terminate()
。
相反,你应该按值抛出异常:
throw Mage::Exception("failed to initialize OpenGL");
如果你发布的代码确实是你正在使用的,你会看到控制被转移到你的处理程序。
根据错误信息,您正在为您的项目使用Visual Studio(2010)。除非你把throw包在try/catch块中,否则它将"穿过屋顶"并由c++运行时"处理",这意味着调用abort()。您可能希望在调用堆栈中有这样的东西:
try
{
SomeFunctionThatUltimatelyThrows();
}
catch(Exception & e)
{
// .. handle error - log, resume, exit, whatever
}
还要注意Scott Meyers的建议,即总是通过引用捕获异常。"异常":如果你正在使用MFC CExceptions,你想通过指针捕获并调用Delete方法来自毁基于堆的异常。
根据你的编辑,你可能在抛出"按指针"和捕获"按引用"之间存在不匹配。如果你已经解决了这个问题,并且仍然没有让你的catch块执行,你可以尝试通过使用CRT SetAbortHandler来安装你自己的abort函数来调试abort()调用。这可以简单地链接到现有的,但将提供一个机会来设置一个断点,并检查调用堆栈,看看哪里出了问题。
c++的try-catch-throw逻辑。注意,这并不包括基于RAII/堆栈的分配/销毁。
- 当你抛出一个异常时,这个异常被称为"正在传播"。它沿着调用堆栈向上传播,直到找到可以处理它的第一个处理程序(因此它被捕获),或者直到它到达调用堆栈的根。
- 如果被捕获,则从捕获异常的点开始继续执行。异常在catch块的末尾被销毁。 如果它找到根,它调用std::unhandled_exception,它通常调用std::terminate,后者通常调用abort()。简而言之,一切都要尽快放下。
- 如果在异常正在传播时抛出异常,则会同时有两个异常在传播。Java和c#都有处理这种情况的可爱方法,但这种情况从一开始就不应该发生——没有异常处理程序在逻辑上处理异常的组合。当一个异常正在传播时不要抛出异常。即使你不使用std::uncaught_exception(),这个规则也不难遵守。
- 当展开堆栈/传播异常时,在堆栈上找到的所有对象都被销毁。这些析构函数永远不应该抛出异常——毕竟,当销毁对象"失败"时,在析构函数之后还能做些什么来修复它呢? 总是按值抛出,按引用捕获。如果你扔&通过指针捕获,你很可能会泄漏一些东西,这是不可能的引用。如果按值捕获,则将剥离派生的异常类型。
- 在您的软件的根,包括一个捕获所有-
catch(...)
。这不能让你知道你到底抓住了什么,但至少你可以安全坠毁。当被调用的代码可能抛出你不知道的"某些东西"时,也要这样做。
- 使用调试/崩溃报告将应用程序部署到客户端
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- 如何找出应用程序崩溃的原因 - Win 10 LTSB
- 操纵安卓相机的深度图导致应用程序崩溃
- 为什么从文件获取图标时应用程序有时会崩溃?
- 在 Ubuntu 服务器上运行 QT 应用程序时崩溃
- 调用 java 的回调() 时应用程序崩溃.由于 detatchThread 而获得运行时错误
- Qt应用程序找不到第三方DLL并崩溃
- 由于____chkstk_darwin,在Catalina上使用部署10.10编译的MacOS应用程序在HighSierra版本<崩溃
- QCompleter set模型使应用程序崩溃
- Qt 5 应用程序崩溃并出现"qLineEdit::setText"
- 切换NvAPI_Stereo_Deactivate/NvAPI_Stereo_activate会使unity应用程序崩溃
- Opencv在2013年第5季度不起作用.应用程序总是在窗口中崩溃
- eglSwapBuffers上的应用程序崩溃
- C 多线程崩溃应用程序
- 加载的 obj 模型闪烁并崩溃应用程序
- strcats func 崩溃应用程序
- 生成的Protobuf代码崩溃应用程序
- C++字符串::查找崩溃应用程序
- av_free随机崩溃应用程序-FFMPEG C++