diff --git a/bin/varnishtest/vtc_log.c b/bin/varnishtest/vtc_log.c index 5fa44e7bee5..67aea1de31b 100644 --- a/bin/varnishtest/vtc_log.c +++ b/bin/varnishtest/vtc_log.c @@ -40,6 +40,7 @@ #include "vtc_log.h" #include "vtim.h" +#include "vbt.h" static pthread_mutex_t vtclog_mtx; static char *vtclog_buf; @@ -296,20 +297,30 @@ static void v_noreturn_ vtc_log_VAS_Fail(const char *func, const char *file, int line, const char *cond, enum vas_e why) { + char buf[4096] = ""; struct vtclog *vl; int e = errno; (void)why; + + if (VBT_dump(sizeof buf, buf) < 0) { + bprintf(buf, "Failed to print backtrace: %d (%s)\n", + errno, strerror(errno)); + } + vl = pthread_getspecific(log_key); if (vl == NULL || vl->act) { fprintf(stderr, "Assert error in %s(), %s line %d:\n" - " Condition(%s) not true. (errno=%d %s)\n", - func, file, line, cond, e, strerror(e)); + " Condition(%s) not true. (errno=%d %s)\n" + "%s\n", + func, file, line, cond, e, strerror(e), buf); } else vtc_fatal(vl, "Assert error in %s(), %s line %d:" " Condition(%s) not true." - " Errno=%d %s", func, file, line, cond, e, strerror(e)); + " Errno=%d %s\n" + "%s\n", + func, file, line, cond, e, strerror(e), buf); abort(); } diff --git a/include/vbt.h b/include/vbt.h index bd3a384b937..c2c8b28f2c4 100644 --- a/include/vbt.h +++ b/include/vbt.h @@ -31,3 +31,4 @@ struct vsb; void VBT_format(struct vsb *); +int VBT_dump(size_t len, char [len]); diff --git a/lib/libvarnish/vas.c b/lib/libvarnish/vas.c index b64418cc956..c45202c3c2f 100644 --- a/lib/libvarnish/vas.c +++ b/lib/libvarnish/vas.c @@ -38,6 +38,7 @@ #include #include "vdef.h" +#include "vbt.h" #include "vas.h" @@ -57,37 +58,53 @@ VAS_errtxt(int e) vas_f *VAS_Fail_Func v_noreturn_; -void v_noreturn_ -VAS_Fail(const char *func, const char *file, int line, +static void +vas_default(const char *func, const char *file, int line, const char *cond, enum vas_e kind) { int err = errno; + char buf[4096]; - if (VAS_Fail_Func != NULL) { - VAS_Fail_Func(func, file, line, cond, kind); + if (kind == VAS_MISSING) { + fprintf(stderr, + "Missing error handling code in %s(), %s line %d:\n" + " Condition(%s) not true.\n", + func, file, line, cond); + } else if (kind == VAS_INCOMPLETE) { + fprintf(stderr, + "Incomplete code in %s(), %s line %d:\n", + func, file, line); + } else if (kind == VAS_WRONG) { + fprintf(stderr, + "Wrong turn in %s(), %s line %d: %s\n", + func, file, line, cond); } else { - if (kind == VAS_MISSING) { - fprintf(stderr, - "Missing error handling code in %s(), %s line %d:\n" - " Condition(%s) not true.\n", - func, file, line, cond); - } else if (kind == VAS_INCOMPLETE) { - fprintf(stderr, - "Incomplete code in %s(), %s line %d:\n", - func, file, line); - } else if (kind == VAS_WRONG) { - fprintf(stderr, - "Wrong turn in %s(), %s line %d: %s\n", - func, file, line, cond); - } else { - fprintf(stderr, - "Assert error in %s(), %s line %d:\n" - " Condition(%s) not true.\n", - func, file, line, cond); - } - if (err) - fprintf(stderr, - " errno = %d (%s)\n", err, strerror(err)); + fprintf(stderr, + "Assert error in %s(), %s line %d:\n" + " Condition(%s) not true.\n", + func, file, line, cond); + } + if (err) { + fprintf(stderr, + " errno = %d (%s)\n", err, strerror(err)); } + + if (VBT_dump(sizeof buf, buf) < 0) { + bprintf(buf, "Failed to print backtrace: %d (%s)\n", + errno, strerror(errno)); + } + + fprintf(stderr, "%s", buf); +} + +void v_noreturn_ +VAS_Fail(const char *func, const char *file, int line, + const char *cond, enum vas_e kind) +{ + + if (VAS_Fail_Func != NULL) + VAS_Fail_Func(func, file, line, cond, kind); + else + vas_default(func, file, line, cond, kind); abort(); } diff --git a/lib/libvarnish/vbt.c b/lib/libvarnish/vbt.c index f68906e51ee..27225d732ae 100644 --- a/lib/libvarnish/vbt.c +++ b/lib/libvarnish/vbt.c @@ -150,3 +150,19 @@ VBT_format(struct vsb *vsb) vbt_execinfo(vsb); #endif } + +int +VBT_dump(size_t len, char buf[len]) +{ + struct vsb vsb[1]; + + if (buf == NULL || VSB_init(vsb, buf, len) == NULL) + return (-1); + + VSB_printf(vsb, "Backtrace:\n"); + VSB_indent(vsb, 2); + VBT_format(vsb); + VSB_indent(vsb, -2); + + return (0); +}