summaryrefslogtreecommitdiff
path: root/src/common/nullpo.c
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2019-11-26 03:09:38 +0300
committerAndrei Karas <akaras@inbox.ru>2020-03-30 06:35:10 +0300
commit80372d4ca082d6d35f89e99094544fc892cfeb75 (patch)
tree515097f9168bc9b568820ced30bf67b562ed1c80 /src/common/nullpo.c
parented5d2d7222401f17f9c8ded96ff0e86aba8e88d6 (diff)
downloadhercules-80372d4ca082d6d35f89e99094544fc892cfeb75.tar.gz
hercules-80372d4ca082d6d35f89e99094544fc892cfeb75.tar.bz2
hercules-80372d4ca082d6d35f89e99094544fc892cfeb75.tar.xz
hercules-80372d4ca082d6d35f89e99094544fc892cfeb75.zip
Add libbacktrace
Diffstat (limited to 'src/common/nullpo.c')
-rw-r--r--src/common/nullpo.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/src/common/nullpo.c b/src/common/nullpo.c
index dfb938708..e43b91bb8 100644
--- a/src/common/nullpo.c
+++ b/src/common/nullpo.c
@@ -28,13 +28,41 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_EXECINFO
+#ifdef HAVE_LIBBACKTRACE
+#include "libbacktrace/backtrace.h"
+#include "libbacktrace/backtrace-supported.h"
+#elif defined(HAVE_EXECINFO)
#include <execinfo.h>
-#endif // HAVE_EXECINFO
+#endif // HAVE_LIBBACKTRACE
+
static struct nullpo_interface nullpo_s;
struct nullpo_interface *nullpo;
+#ifdef HAVE_LIBBACKTRACE
+static void nullpo_error_callback(void *data, const char *msg, int errnum)
+{
+ ShowError("Error: %s (%d)", msg, errnum);
+}
+
+static int nullpo_print_callback(void *data, uintptr_t pc, const char *filename, int lineno, const char *function)
+{
+ ShowError("0x%lx %s\n",
+ (unsigned long) pc,
+ function == NULL ? "???" : function);
+ ShowError("\t%s:%d\n",
+ filename == NULL ? "???" : filename,
+ lineno);
+ return 0;
+}
+
+static void nullpo_backtrace_print(struct backtrace_state *state)
+{
+ backtrace_full(state, 0, nullpo_print_callback, nullpo_error_callback, state);
+}
+
+#endif // HAVE_LIBBACKTRACE
+
/**
* Reports failed assertions or NULL pointers
*
@@ -46,12 +74,12 @@ struct nullpo_interface *nullpo;
*/
static void assert_report(const char *file, int line, const char *func, const char *targetname, const char *title)
{
-#ifdef HAVE_EXECINFO
+#if !defined(HAVE_LIBBACKTRACE) && defined(HAVE_EXECINFO)
void *array[10];
int size;
char **strings;
int i;
-#endif // HAVE_EXECINFO
+#endif // !defined(HAVE_LIBBACKTRACE) && defined(HAVE_EXECINFO)
if (file == NULL)
file = "??";
@@ -60,14 +88,18 @@ static void assert_report(const char *file, int line, const char *func, const ch
ShowError("--- %s --------------------------------------------\n", title);
ShowError("%s:%d: '%s' in function `%s'\n", file, line, targetname, func);
-#ifdef HAVE_EXECINFO
+#ifdef HAVE_LIBBACKTRACE
+ struct backtrace_state *state = backtrace_create_state("hercules", BACKTRACE_SUPPORTS_THREADS, nullpo_error_callback, NULL);
+ nullpo_backtrace_print(state);
+#elif defined(HAVE_EXECINFO)
size = (int)backtrace(array, 10);
strings = backtrace_symbols(array, size);
for (i = 0; i < size; i++)
ShowError("%s\n", strings[i]);
free(strings);
-#endif // HAVE_EXECINFO
+#endif // HAVE_LIBBACKTRACE
ShowError("--- end %s ----------------------------------------\n", title);
+
}
/**