简体   繁体   English

无法捕获自定义std :: runtime_error

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM