C ++:自定义格式,用于设置main()

时间:2018-10-07 00:44:59

标签: c++ exception main

我正在创建一个包含可能引发异常的函数的库。为了调试使用我的库的程序,我想提供一种自定义格式方法,如果main()未捕获到这些异常,它将为程序员提供有关这些异常的更多信息。

通常,可以从最终用户编写的main function()中调用我的库。最终用户不会在try..catch中放置main()块,因为最终用户不会期望这些异常(实际上应该避免在我的库和{{ 1}},但不是,这就是我们需要调试的东西。

main()

运行上面的程序,我得到:

// The following example would actually be multiple files,
// but to keep this example simple, put it in "<filename>"
// and compile the following with "g++ <filename>".


// library file

class My_Exception
{
public:
  char const* msg;
  My_Exception(char const* msg) : msg(msg) {}
};

void Library_Function(bool rarely_true = false)
{
  if (rarely_true)
    throw My_Exception("some exceptional thing");
}
// note to discerning user: if you use the "rarely_true" feature,
// be sure to remember to catch "My_Exception"!!!!


// intermediate, buggy, library (written by someone else)

void Meta_Function()
{
  Library_Function(true); // hahahaha not my problem!
}


// main program (written by yet someone else, no "try..except"
// allowed here)

int main()
{
  Meta_Function();
}

我喜欢一条错误消息告诉我未捕获的异常的方式。我想知道向terminate called after throwing an instance of 'My_Exception' Abort (core dumped) 添加一个钩子的最佳方法,以便在这种情况下也可以打印My_Exception字符串。

我愿意在运行时系统中注册回调,或向msg添加方法,但是我不想惹My_Exception本身。 (我知道可以通过告诉链接程序使用具有main()的其他入口点并在其中包装try..catch来解决此问题,但是要使最终用户采用某些东西很难这样)。

显然,main()之后已经有一些异常检查代码,因为上面的消息已经打印出来了。堆栈跟踪为:

main()

此外:我一点也不明白为什么#0 0x0000155554c0d428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 #1 0x0000155554c0f02a in __GI_abort () at abort.c:89 #2 0x000015555502e8f7 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #3 0x0000155555034a46 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #4 0x0000155555034a81 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x0000155555034cb4 in __cxa_throw () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6 #6 0x00000000004006eb in Library_Function() () #7 0x00000000004006f4 in main () (gdb) 说程序在gdb中中止。听起来错了;它应该至少在Library_Function无法捕获异常之后从main()退出。必须有一些语言细节,例如它保留堆栈,直到处理异常为止?无论如何,我离题了。

在这种情况下,也许我们可以扩展main()std::terminate()或其他一些运行时组件来打印cxa__throw()

这个问题有何不同

为什么我不能从抛出异常中打印出错误? 2个答案-相似,但1.我的问题涉及一个异常对象(不是字符串),因此有关自定义格式设置(在问题标题中)很重要。 2.标题中缺少“未捕获”关键字,因此很难找到

未通过what()1答案打印的重新抛出异常的自定义错误消息 -1.在他们的问题中已经包含了我的问题的答案,因此不能是同一问题。除非您认为“用什么工具砸钉子”与“为什么我的锤子不起作用”是同样的问题。 2.标题中缺少关键字“未捕获”

针对“虚拟常量字符 ro_err :: StdErr :: what()const的更宽松的抛出说明符1个答案* -1.在他们的问题中已经包含了我的问题的答案,因此不能是同一问题。除非您认为“用什么工具砸钉子”与“为什么我的锤子不起作用”是同样的问题。 2.标题中缺少关键字“未捕获”

1 个答案:

答案 0 :(得分:1)

按照πάνταῥεῖ的建议,您可以尝试

class myexception : public exception
{
public:    
    const char* what() const noexcept override
    {
        char* ch = "some exceptional thing";
        return ch;
    }
};    

void Library_Function(bool rarely_true = false)
{
    if (rarely_true)
        throw myexception();
}

int main()
{
    try 
    {
        Library_Function(true);
    }
    catch (myexception& err)
    {
        std::cout << err.what();
    }
    return 0;
}