昨天花了不少时间debug客户碰到的一个蹊跷的程序错误。最终发现了问题是由一个C++异常抛出后无法catch到而导致的( 喏,这位老兄也提出了同样的问题)。此前一直自以为exception总是可以被安全catch到的。如果你也这么认为的话,呵呵, 那么你也应该去翻翻C++文档了。
查阅了c++文档后发现,在以下情况,exception并不会被抛出。取而代之的是,terminate()将被调用。
- when the exception handling mechanism, after completing evaluation of the expression to be thrown but before the exception is caught (except.throw), calls a user function that exits via an uncaught exception,*
- when the exception handling mechanism cannot find a handler for a thrown exception (except.handle), or
- when the destruction of an object during stack unwinding (except.ctor) exits using an exception, or
- when construction or destruction of a non-local object with static storage duration exits using an exception (basic.start.init), or
- when execution of a function registered with atexit exits using an exception (lib.support.start.term), or
- when a throw-expression with no operand attempts to rethrow an exception and no exception is being handled (except.throw), or
- when unexpected throws an exception which is not allowed by the previously violated exception-specification, and std::bad_exception is not included in that exception-specification (except.unexpected), or
- when the implementation's default unexpected_handler is called (lib.unexpected.handler)
之所以说问题蹊跷, 在于在客户环境下似乎任何exception都最终被terminate掉。如下几行代码编译执行后得到输出为"terminated!"!
#include <iostream.h>
using std::set_terminate;
void myterminate()
{
cout<<"terminated!"<<endl;
exit(1);
}
int main()
{
set_terminate(myterminate);
try {
throw 10;
}
catch (int& test)
{
cout<<"catched!"<<endl;
}
return 0;
}
该问题只在gcc-3.3的库libstdc++.so上发现。但还是不敢妄下结论是gcc-3.3的bug。