Я создаю библиотеку, которая содержит функции, которые могут генерировать исключения.Для отладки программ, использующих мою библиотеку, я хотел бы предоставить пользовательский метод формата, который даст программисту больше информации об этих исключениях, если они не найдены main()
.
Как правило, моя библиотека может быть вызванаиз main
функции (), написанной конечным пользователем .Конечный пользователь не помещает блок try..catch
в main()
, потому что конечный пользователь не ожидает этих исключений (их на самом деле следует избегать и / или отлавливать другими ошибочными библиотеками, между моей библиотекой и 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()
или какой-либо другой компонент времени выполнения для печати msg
в этом случае?
Как этот вопросотличается
Почему я не могу распечатать ошибку из моего исключения броска?2 ответа - похоже, но 1. мой вопрос связан с объектом исключения (не строкой), и поэтому вопрос о пользовательском форматировании (в заголовке вопроса) является актуальным.2. отсутствует ключевое слово «uncaught» в заголовке, поэтому его трудно найти
Пользовательское сообщение об ошибке повторно выданного исключения, не напечатанное тем, что () 1 ответ - 1. уже содержитответь на мой вопрос в своем вопросе, поэтому не может быть того же вопроса.Если вы не считаете, «какой инструмент колотит гвоздем», то же самое, что и «почему мой молот не работает».2. отсутствует ключевое слово «uncaught» из заголовка
указатель более свободного броска для 'virtual const char ro_err :: StdErr :: what () const' 1 ответ * - 1. уже содержитответ на мой вопрос в их вопросе, поэтому не может быть того же вопроса.Если вы не считаете, «какой инструмент колотит гвоздем», то же самое, что и «почему мой молот не работает».2. пропущено ключевое слово "uncaught" из заголовка