24 #include <core/exception.h>
25 #include <core/threading/mutex.h>
35 # include <execinfo.h>
150 __type_id =
"unknown";
156 if ( format != NULL ) {
158 va_start(arg, format);
181 __type_id =
"unknown";
187 if ( format != NULL ) {
189 va_start(arg, format);
191 if ( asprintf(&ext_format,
"%s (errno: %i, %s)", format, errno, strerror(errno)) == -1 ) {
199 append_nolock(
"Exception with errno=%i (%s)", errno, strerror(errno));
240 messages_mutex =
new Mutex();
244 messages_iterator = NULL;
247 __type_id = exc.__type_id;
261 __type_id =
"unknown";
325 if (format == NULL)
return;
328 va_start(arg, format);
344 if (format == NULL)
return;
347 va_start(arg, format);
364 if (format == NULL)
return;
366 messages_mutex->lock();
367 append_nolock_va(format, va);
368 messages_mutex->unlock();
395 va_start(arg, format);
398 if ( vasprintf(&msg, format, arg) == -1 ) {
399 msg = strdup(format);
432 if ( vasprintf(&msg, format, ap) == -1 ) {
433 msg = strdup(format);
436 if ( messages == NULL ) {
439 messages->next = NULL;
441 messages_end = messages;
463 if ( vasprintf(&msg, format, ap) == -1 ) {
464 msg = strdup(format);
467 if ( messages == NULL ) {
470 messages->next = NULL;
472 messages_end = messages;
477 messages_end->next = ml;
493 if ( messages == NULL ) {
496 messages->next = NULL;
498 messages_end = messages;
503 messages_end->next = ml;
521 messages_mutex =
new Mutex();
535 messages_mutex->lock();
536 exc.messages_mutex->lock();
539 messages_iterator = exc.messages;
540 while ( messages_iterator ) {
541 append_nolock(messages_iterator->msg);
542 messages_iterator = messages_iterator->next;
545 exc.messages_mutex->unlock();
546 messages_mutex->unlock();
567 int size = backtrace(array, 25);
568 char ** symbols = backtrace_symbols(array, size);
570 printf(
"Backtrace:\n");
571 for (
int i = 0; i < size; ++i) {
572 printf(
" %s\n", symbols[i]);
577 printf(
"Backtrace not available on current system\n");
588 #ifdef HAVE_BACKTRACE
590 int size = backtrace(array, 25);
591 char ** symbols = backtrace_symbols(array, size);
593 size_t total_size = 1;
594 for (
int i = 0; i < size; ++i) {
595 total_size += strlen(symbols[i]) + 1;
597 char *rv = (
char *)calloc(1, total_size);
599 for (
int i = 0; i < size; ++i) {
600 sprintf(r,
"%s\n", symbols[i]);
601 r += strlen(symbols[i]);
606 char *rv = strdup(
"Backtrace not available on current system\n");
623 "=================================================== BEGIN OF EXCEPTION =====\n");
625 fprintf(stderr,
"No messages recorded.\n");
634 "=================================================== END OF EXCEPTION =======\n");
669 return "Unknown error";
708 mlist = message_list;
726 this->mlist = i.mlist;
736 if ( mlist != NULL ) {
751 if ( mlist != NULL ) {
765 return (mlist == i.mlist);
776 return (mlist != i.mlist);
787 if ( mlist != NULL ) {
802 this->mlist = i.mlist;
message_list_t * messages_end
Pointer that points to the very last message.
Mutex * messages_mutex
Mutex to protect operations on messages list.
int get_errno()
Get errno.
Fawkes library namespace.
void unlock()
Unlock the mutex.
Exception()
Constructor for subclasses.
virtual void raise()
This can be used to throw this exception.
int _errno
Error number, should be used if the error was caused by a method that supplies errno.
void prepend_nolock_va(const char *format, va_list va)
Prepend messages without lock by formatted string.
Message iterator for exceptions.
virtual ~Exception()
Destructor.
iterator()
Plain constructor.
iterator end()
Get end iterator for messages.
char * generate_backtrace() const
Generate backtrace string.
virtual const char * what() const
Get primary string.
iterator & operator++()
Prefix ++ operator.
Base class for exceptions in Fawkes.
void append_nolock_va(const char *format, va_list va)
Append messages without lock by formatted string.
void append_nolock(const char *format,...)
Append messages without lock.
void print_backtrace() const
Prints a backtrace.
const char * type_id() const
Get type ID.
message_list_t * messages
List of messages.
void prepend(const char *format,...)
Prepend messages to the message list.
message_list_t * messages_iterator
Iterator to iterate over messages.
const char * operator*() const
Get current message.
iterator begin()
Get iterator for messages.
void append_va(const char *format, va_list va)
Append messages to the message list.
Internal exception message list.
void print_trace()
Prints trace to stderr.
iterator & operator=(const iterator &i)
Assignment operator.
bool operator==(const iterator &i) const
Check equality.
void set_type_id(const char *id)
Set exception type ID.
message_list_t * next
pointer to next element, NULL if last element
void lock()
Lock this mutex.
void copy_messages(const Exception &exc)
Copy messages from given exception.
Exception & operator=(const Exception &exc)
Assign an Exception.
Mutex mutual exclusion lock.
bool operator!=(const iterator &i) const
Check inequality.
void append_nolock_nocopy(char *msg)
Append message without copying.
void append(const char *format,...)
Append messages to the message list.
char * msg
pointer to message, may not be NULL, will be freed in dtor