[英]Cannot catch custom std::runtime_error
In my code I throw my custom file_error exception, which is derived from std::runtime_error. 在我的代码中,我抛出了自定义的file_error异常,该异常是从std :: runtime_error派生的。 In a different module I catch exceptions for that operation and want to handle my file_error like this:
在另一个模块中,我捕获了该操作的异常,并想像这样处理我的file_error:
try
{
base::create_directory(INVALID_NAME, 0700);
...
}
catch (const base::file_error &exc)
{
...
}
catch(std::runtime_error &exc)
{
...
}
catch(std::exception &exc)
{
...
}
file_error is declared as: file_error声明为:
namespace base {
class file_error : public std::runtime_error
{
int sys_error_code;
public:
file_error(const std::string &text, int err);
error_code code();
int sys_code();
};
}
However, the catch branch for file_error is never triggered. 但是,永远不会触发file_error的catch分支。 Either I end up in the runtime_error branch or, if I remove that, in the exception branch.
我要么进入runtime_error分支,要么删除(异常)。
However, this works fine in Linux + Win (gcc, VS) while it does not work on Mac (clang). 但是,这在Linux + Win(gcc,VS)下工作正常,而在Mac(clang)上不工作。 Any idea what could be wrong here?
知道这里有什么问题吗?
Update: 更新:
Here's the lldb output when I reach the runtime_error branch: 这是我到达runtime_error分支时的lldb输出:
(lldb) p exc
(const base::file_error) $0 = {
std::runtime_error = {
__imp_ = (__imp_ = 0x0000000000000000)
}
sys_error_code = 13923331
}
That clearly indicates the exception is indeed of type base::file_error. 这清楚地表明异常确实是base :: file_error类型。 It's just not catched in its associated catch block.
它只是没有被关联的catch块捕获。
Update 2: 更新2:
Declaring an own error based on file_error in the same file as the test code above like this: 在与上述测试代码相同的文件中,基于file_error声明自己的错误,如下所示:
class test_error : base::file_error {
public:
test_error(const std::string &s) : base::file_error(s, 0) {};
};
allows me to catch it in a test_error block and in a catch-all block, but not in base::file_error, std::runtime_error or std::exception blocks. 让我可以在test_error块和全包块中捕获它,但不能在base :: file_error,std :: runtime_error或std :: exception块中捕获。 Weird.
奇怪的。
Update 3: 更新3:
After a lot of experimenting I now think this is a type mismatch issue, similar to the ODR-violation but a different kind. 经过大量的试验,我现在认为这是类型不匹配的问题,类似于违反ODR的问题,但类型不同。 The types in the dylib and in the test app are not considered the same and hence the exception is not catched, unless I throw that base::file_error exeption directly in the test code.
dylib和测试应用程序中的类型不相同,因此不会捕获异常,除非我直接在测试代码中抛出base :: file_error异常。
class test_error : base::file_error
allows me to catch it in a test_error block and in a catch-all block, but not in base::file_error, std::runtime_error or std::exception blocks.
让我可以在test_error块和全包块中捕获它,但不能在base :: file_error,std :: runtime_error或std :: exception块中捕获。
Your exception classes need to derive publicly from base exception classes. 您的异常类需要从基本异常类公开地派生。 Otherwise you won't be able to catch them via the base class:
否则,您将无法通过基类捕获它们:
class test_error : public base::file_error
The solution for this problem is to avoid using the compiler option -fvisibility=hidden
(or make it default) in the test application. 解决此问题的方法是避免在测试应用程序中使用编译器选项
-fvisibility=hidden
(或将其设置为默认值)。 Read more about this here: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options . 在此处阅读有关此内容的更多信息: https : //gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options 。 In particular this part:
特别是这部分:
Note that -fvisibility does affect C++ vague linkage entities.
请注意,-fvisibility确实会影响C ++模糊链接实体。 This means that, for instance, an exception class that is be thrown between DSOs must be explicitly marked with default visibility so that the 'type_info' nodes are unified between the DSOs.
这意味着,例如,必须在DSO之间抛出的异常类必须使用默认可见性进行显式标记,以便在DSO之间统一“ type_info”节点。
An overview of these techniques, their benefits and how to use them is at http://gcc.gnu.org/wiki/Visibility .
有关这些技术及其优势以及使用方法的概述,请参见http://gcc.gnu.org/wiki/Visibility 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.