C++:main() 未捕获的异常的自定义格式
C++: Custom formatting for exceptions uncaught by main()
我正在创建一个库,其中包含可以引发异常的函数。为了调试使用我的库的程序,我想提供一个自定义 format-method,如果它们未被 main()
.
捕获,它将为程序员提供有关这些异常的更多信息
通常,我的库可以从 最终用户 编写的 main
function() 中调用。最终用户不会在 main()
中放置 try..catch
块,因为最终用户不希望出现这些异常(实际上应该避免 and/or 被其他有问题的库捕获,在我的库和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()
来解决,但是很难让 end-user 到采用类似的东西)。
显然在 main()
之后已经有一些 exception-checking 代码,因为上面的消息被打印出来了。堆栈跟踪是:
#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()
或其他一些 运行 时间组件来打印 msg
?
这个问题有什么不同
为什么我不能从抛出的异常中打印出错误? 2 个答案——类似,但 1. 我的问题涉及异常 object(不是字符串),因此关于自定义格式的要点(在问题标题中)是相关的。 2. 标题中缺少关键字"uncaught",很难找到
re-thrown 异常的自定义错误消息未由 what() 打印 1 个回答
-- 1. 在他们的问题中已经包含了我的问题的答案,所以不能是同一个问题。除非你认为 "what tool pounds a nail" 与 "why isn't my hammer working" 是同一个问题。 2. 标题中缺少关键字 "uncaught"
'virtual const char ro_err::StdErr::what() const' 的宽松抛出说明符 1 个答案*
-- 1. 在他们的问题中已经包含了我的问题的答案,所以不能是同一个问题。除非你认为 "what tool pounds a nail" 与 "why isn't my hammer working" 是同一个问题。 2. 标题中缺少关键字 "uncaught"
根据πìντα ῥεῖ的建议,你可以试试这个
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;
}
我正在创建一个库,其中包含可以引发异常的函数。为了调试使用我的库的程序,我想提供一个自定义 format-method,如果它们未被 main()
.
通常,我的库可以从 最终用户 编写的 main
function() 中调用。最终用户不会在 main()
中放置 try..catch
块,因为最终用户不希望出现这些异常(实际上应该避免 and/or 被其他有问题的库捕获,在我的库和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()
来解决,但是很难让 end-user 到采用类似的东西)。
显然在 main()
之后已经有一些 exception-checking 代码,因为上面的消息被打印出来了。堆栈跟踪是:
#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()
或其他一些 运行 时间组件来打印 msg
?
这个问题有什么不同
为什么我不能从抛出的异常中打印出错误? 2 个答案——类似,但 1. 我的问题涉及异常 object(不是字符串),因此关于自定义格式的要点(在问题标题中)是相关的。 2. 标题中缺少关键字"uncaught",很难找到
re-thrown 异常的自定义错误消息未由 what() 打印 1 个回答 -- 1. 在他们的问题中已经包含了我的问题的答案,所以不能是同一个问题。除非你认为 "what tool pounds a nail" 与 "why isn't my hammer working" 是同一个问题。 2. 标题中缺少关键字 "uncaught"
'virtual const char ro_err::StdErr::what() const' 的宽松抛出说明符 1 个答案* -- 1. 在他们的问题中已经包含了我的问题的答案,所以不能是同一个问题。除非你认为 "what tool pounds a nail" 与 "why isn't my hammer working" 是同一个问题。 2. 标题中缺少关键字 "uncaught"
根据πìντα ῥεῖ的建议,你可以试试这个
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;
}