From ee8d9ae19d515e3d4f5e1192f29fd8fa48a2da0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20O=2E=20Sel=C3=A5sdal?= Date: Wed, 6 Mar 2013 21:58:56 +0100 Subject: [PATCH] Add a uc_backtrace_buf() functio --- include/ucore/ucore_backtrace.h | 16 ++++++++++++++++ src/ucore_backtrace.c | 28 ++++++++++++++++++++++++++++ test/backtrace.c | 14 ++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/include/ucore/ucore_backtrace.h b/include/ucore/ucore_backtrace.h index b4bb1e5..0110165 100644 --- a/include/ucore/ucore_backtrace.h +++ b/include/ucore/ucore_backtrace.h @@ -2,7 +2,23 @@ #define UC_BACKTRACE_H_ #define UC_BACTRACE_STDERR uc_backtrace_fd(2) +#include +/** + * Print a stacktrace to the given file descriptor. + * + * @param fd filedescriptor to write to. + */ void uc_backtrace_fd(int fd); +/** + * Print a stactrace to the given buffer + * (Note that unlike uc_backtrace_fd(), this function + * does malloc() call and may fail in a signal handler or + * if memory is corrupted. + * + * @param buf buffer to place the stacktrace in. + * @param len length of buffer + */ +void uc_backtrace_buf(char *buf, size_t len); #endif diff --git a/src/ucore_backtrace.c b/src/ucore_backtrace.c index 3a38dbe..5110693 100644 --- a/src/ucore_backtrace.c +++ b/src/ucore_backtrace.c @@ -1,5 +1,7 @@ #include #include +#include +#include #define MAX_BACKTRACE_SYMBOLS 96 @@ -20,4 +22,30 @@ void uc_backtrace_fd(int fd) backtrace_symbols_fd(syms, ptrs, fd); } +void uc_backtrace_buf(char *buf, size_t len) +{ + void *buffer[MAX_BACKTRACE_SYMBOLS]; + int ptrs; + char **lines; + size_t remaining = len; + int i; + + ptrs = backtrace(buffer, MAX_BACKTRACE_SYMBOLS); + buf[0] = 0; + + lines = backtrace_symbols(buffer, ptrs); + for (i = 1; i < ptrs; i++) { + + int rc = snprintf(buf, remaining, "%s\n", lines[i]); + + if (rc <= 0 || (size_t)rc >= remaining) { + break; + } + + remaining -= rc; + buf += rc; + } + + free(lines); +} diff --git a/test/backtrace.c b/test/backtrace.c index 93a1a6d..975a5e6 100644 --- a/test/backtrace.c +++ b/test/backtrace.c @@ -1,3 +1,4 @@ +#include #include //note , compiling this without -rdynamic does not @@ -7,9 +8,22 @@ void func2(void) uc_backtrace_fd(2); } +void func3(void) +{ + uc_backtrace_fd(2); +} + +void func4(void) +{ + char trace[256]; + uc_backtrace_buf(trace, sizeof trace); + printf("Stacktrace from %s:\n%s", __func__, trace); +} + void func1(void) { func2(); + func4(); } int main(int argc, char *argv[])