diff options
Diffstat (limited to 'builtins/functions.c')
| -rw-r--r-- | builtins/functions.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/builtins/functions.c b/builtins/functions.c index 4ff7a1a5..d366736e 100644 --- a/builtins/functions.c +++ b/builtins/functions.c @@ -1,9 +1,10 @@ // Built-in functions +#include <errno.h> +#include <execinfo.h> #include <gc.h> #include <gc/cord.h> #include <stdbool.h> #include <stdint.h> -#include <errno.h> #include <stdlib.h> #include <sys/param.h> #include <uninorm.h> @@ -33,6 +34,26 @@ public void fail(CORD fmt, ...) CORD_vfprintf(stderr, fmt, args); fputs("\n", stderr); va_end(args); + + // Print stack trace: + fprintf(stderr, "\x1b[34m"); + fflush(stderr); + void *array[1024]; + size_t size = backtrace(array, sizeof(array)/sizeof(array[0])); + char **strings = strings = backtrace_symbols(array, size); + for (size_t i = 1; i < size; i++) { + char *filename = strings[i]; + const char *cmd = heap_strf("addr2line -e %.*s -fip | sed 's/\\$/./g;s/ at /() at /' >&2", strcspn(filename, "("), filename); + FILE *fp = popen(cmd, "w"); + if (fp) { + char *paren = strchrnul(strings[i], '('); + fprintf(fp, "%.*s\n", strcspn(paren + 1, ")"), paren + 1); + } + pclose(fp); + } + fprintf(stderr, "\x1b[m"); + fflush(stderr); + raise(SIGABRT); } |
