24#include <core/exception.h>
25#include <core/threading/mutex.h>
149 type_id_ =
"unknown";
155 if (format != NULL) {
157 va_start(arg, format);
179 type_id_ =
"unknown";
185 if (format != NULL) {
187 va_start(arg, format);
189 if (asprintf(&ext_format,
"%s (errno: %i, %s)", format,
_errno, strerror(
_errno)) == -1) {
237 messages_mutex =
new Mutex();
241 messages_iterator = NULL;
244 type_id_ = exc.type_id_;
257 type_id_ =
"unknown";
321 va_start(arg, format);
340 va_start(arg, format);
359 messages_mutex->lock();
360 append_nolock_va(format, va);
361 messages_mutex->unlock();
386 va_start(arg, format);
389 if (vasprintf(&msg, format, arg) == -1) {
390 msg = strdup(format);
422 if (vasprintf(&msg, format, ap) == -1) {
423 msg = strdup(format);
426 if (messages == NULL) {
429 messages->next = NULL;
431 messages_end = messages;
452 if (vasprintf(&msg, format, ap) == -1) {
453 msg = strdup(format);
456 if (messages == NULL) {
459 messages->next = NULL;
461 messages_end = messages;
466 messages_end->next = ml;
481 if (messages == NULL) {
484 messages->next = NULL;
486 messages_end = messages;
491 messages_end->next = ml;
508 messages_mutex =
new Mutex();
521 messages_mutex->lock();
522 exc.messages_mutex->lock();
525 messages_iterator = exc.messages;
526 while (messages_iterator) {
527 append_nolock(messages_iterator->msg);
528 messages_iterator = messages_iterator->next;
531 exc.messages_mutex->unlock();
532 messages_mutex->unlock();
551 int size = backtrace(array, 25);
552 char **symbols = backtrace_symbols(array, size);
554 printf(
"Backtrace:\n");
555 for (
int i = 0; i < size; ++i) {
556 printf(
" %s\n", symbols[i]);
561 printf(
"Backtrace not available on current system\n");
573 int size = backtrace(array, 25);
574 char **symbols = backtrace_symbols(array, size);
576 size_t total_size = 1;
577 for (
int i = 0; i < size; ++i) {
578 total_size += strlen(symbols[i]) + 1;
580 char *rv = (
char *)calloc(1, total_size);
582 for (
int i = 0; i < size; ++i) {
583 sprintf(r,
"%s\n", symbols[i]);
584 r += strlen(symbols[i]);
589 char *rv = strdup(
"Backtrace not available on current system\n");
604 fprintf(stderr,
"=================================================== BEGIN OF EXCEPTION =====\n");
606 fprintf(stderr,
"No messages recorded.\n");
614 fprintf(stderr,
"=================================================== END OF EXCEPTION =======\n");
647 return "Unknown error";
668 return "Unknown error";
704 mlist = message_list;
720 this->mlist = i.mlist;
756 return (mlist == i.mlist);
766 return (mlist != i.mlist);
790 this->mlist = i.mlist;
Message iterator for exceptions.
iterator()
Plain constructor.
bool operator!=(const iterator &i) const
Check inequality.
const char * operator*() const
Get current message.
iterator & operator++()
Prefix ++ operator.
bool operator==(const iterator &i) const
Check equality.
iterator & operator=(const iterator &i)
Assignment operator.
Base class for exceptions in Fawkes.
void print_trace() noexcept
Prints trace to stderr.
virtual const char * what() const noexcept
Get primary string.
Mutex * messages_mutex
Mutex to protect operations on messages list.
iterator end() noexcept
Get end iterator for messages.
message_list_t * messages_end
Pointer that points to the very last message.
message_list_t * messages
List of messages.
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
void prepend_nolock_va(const char *format, va_list va) noexcept
Prepend messages without lock by formatted string.
void copy_messages(const Exception &exc) noexcept
Copy messages from given exception.
virtual void raise()
This can be used to throw this exception.
void prepend(const char *format,...) noexcept
Prepend messages to the message list.
void set_type_id(const char *id)
Set exception type ID.
void print_backtrace() const noexcept
Prints a backtrace.
void append_va(const char *format, va_list va) noexcept
Append messages to the message list.
void append(const char *format,...) noexcept
Append messages to the message list.
int get_errno() noexcept
Get errno.
void append_nolock(const char *format,...) noexcept
Append messages without lock.
void append_nolock_va(const char *format, va_list va) noexcept
Append messages without lock by formatted string.
Exception() noexcept
Constructor for subclasses.
void append_nolock_nocopy(char *msg) noexcept
Append message without copying.
message_list_t * messages_iterator
Iterator to iterate over messages.
int _errno
Error number, should be used if the error was caused by a method that supplies errno.
const char * type_id() const
Get type ID.
Exception & operator=(const Exception &exc) noexcept
Assign an Exception.
iterator begin() noexcept
Get iterator for messages.
virtual ~Exception() noexcept
Destructor.
char * generate_backtrace() const noexcept
Generate backtrace string.
Mutex mutual exclusion lock.
void lock()
Lock this mutex.
void unlock()
Unlock the mutex.
Fawkes library namespace.
Internal exception message list.
message_list_t * next
pointer to next element, NULL if last element
char * msg
pointer to message, may not be NULL, will be freed in dtor