[master] 7392333a9 vbt: Format back-traces from libvarnish

Nils Goroll nils.goroll at uplex.de
Mon Jun 3 13:15:06 UTC 2024


commit 7392333a9cf5eac64aa28c36007e3e8831afc306
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Tue Feb 14 13:51:08 2023 +0100

    vbt: Format back-traces from libvarnish
    
    This is done in a VSB to match what the panic code is currently doing.
    
    When libunwind is used but fails to produce a back-trace, there is now
    a fallback to the original libexecinfo-based implementation (suggested
    by @asadsa92).

diff --git a/include/Makefile.am b/include/Makefile.am
index 1a68ab4a3..ad4bc2555 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -88,8 +88,8 @@ nobase_pkginclude_HEADERS += \
 # Private headers
 nobase_noinst_HEADERS = \
 	compat/daemon.h \
-	vfl.h \
 	libvcc.h \
+	vbt.h \
 	vcc_interface.h \
 	vcli_serve.h \
 	vcs_version.h \
@@ -99,6 +99,7 @@ nobase_noinst_HEADERS = \
 	vend.h \
 	vev.h \
 	vfil.h \
+	vfl.h \
 	vin.h \
 	vjsn.h \
 	vlu.h \
diff --git a/include/vbt.h b/include/vbt.h
new file mode 100644
index 000000000..bd3a384b9
--- /dev/null
+++ b/include/vbt.h
@@ -0,0 +1,33 @@
+/*-
+ * Copyright (c) 2022 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+struct vsb;
+
+void VBT_format(struct vsb *);
diff --git a/lib/libvarnish/Makefile.am b/lib/libvarnish/Makefile.am
index d06f1b5b2..221091110 100644
--- a/lib/libvarnish/Makefile.am
+++ b/lib/libvarnish/Makefile.am
@@ -18,6 +18,7 @@ libvarnish_la_SOURCES = \
 	vbh.c \
 	vas.c \
 	vav.c \
+	vbt.c \
 	vcli_proto.c \
 	vcli_serve.c \
 	vct.c \
@@ -46,6 +47,11 @@ libvarnish_la_SOURCES = \
 
 libvarnish_la_LIBADD = @PCRE2_LIBS@ $(LIBM)
 
+if WITH_UNWIND
+libvarnish_la_CFLAGS += -DUNW_LOCAL_ONLY $(LIBUNWIND_CFLAGS)
+libvarnish_la_LIBADD += $(LIBUNWIND_LIBS)
+endif
+
 TESTS = \
 	vav_test \
 	vbh_test \
diff --git a/lib/libvarnish/vbt.c b/lib/libvarnish/vbt.c
new file mode 100644
index 000000000..4a2da2c27
--- /dev/null
+++ b/lib/libvarnish/vbt.c
@@ -0,0 +1,143 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2022 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ * Author: Guillaume Quintard <guillaume at varnish-software.com>
+ * Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#ifdef WITH_UNWIND
+#  include <libunwind.h>
+#endif
+
+#include <execinfo.h>
+
+#include "vdef.h"
+#include "vas.h"
+#include "vbt.h"
+#include "vsb.h"
+
+#ifdef WITH_UNWIND
+static int
+vbt_unwind(struct vsb *vsb)
+{
+	unw_cursor_t cursor; unw_context_t uc;
+	unw_word_t ip, sp;
+	unw_word_t offp;
+	char fname[1024];
+	const char *sep;
+	int ret;
+
+	ret = unw_getcontext(&uc);
+	if (ret != 0) {
+		VSB_printf(vsb, "Backtrace not available "
+		    "(unw_getcontext returned %d)\n", ret);
+		return (-1);
+	}
+	ret = unw_init_local(&cursor, &uc);
+	if (ret != 0) {
+		VSB_printf(vsb, "Backtrace not available "
+		    "(unw_init_local returned %d)\n", ret);
+		return (-1);
+	}
+	while (unw_step(&cursor) > 0) {
+		fname[0] = '\0';
+		sep = "";
+		if (!unw_get_reg(&cursor, UNW_REG_IP, &ip)) {
+			VSB_printf(vsb, "ip=0x%lx", (long) ip);
+			sep = " ";
+		}
+		if (!unw_get_reg(&cursor, UNW_REG_SP, &sp)) {
+			VSB_printf(vsb, "%ssp=0x%lx", sep, (long) sp);
+			sep = " ";
+		}
+		if (!unw_get_proc_name(&cursor, fname, sizeof(fname), &offp)) {
+			VSB_printf(vsb, "%s<%s+0x%lx>",
+			    sep, fname[0] ? fname : "<unknown>", (long)offp);
+		}
+		VSB_putc(vsb, '\n');
+	}
+
+	return (0);
+}
+#endif
+
+#define BACKTRACE_LEVELS	20
+
+static void
+vbt_execinfo(struct vsb *vsb)
+{
+	void *array[BACKTRACE_LEVELS];
+	size_t size;
+	size_t i;
+	char **strings;
+	char *p;
+	char buf[32];
+
+	size = backtrace (array, BACKTRACE_LEVELS);
+	if (size > BACKTRACE_LEVELS) {
+		VSB_printf(vsb, "Backtrace not available (ret=%zu)\n", size);
+		return;
+	}
+	for (i = 0; i < size; i++) {
+		bprintf(buf, "%p", array[i]);
+		VSB_printf(vsb, "%s: ", buf);
+		strings = backtrace_symbols(&array[i], 1);
+		if (strings == NULL || strings[0] == NULL) {
+			VSB_cat(vsb, "(?)");
+		} else {
+			p = strings[0];
+			if (!memcmp(buf, p, strlen(buf))) {
+				p += strlen(buf);
+				if (*p == ':')
+					p++;
+				while (*p == ' ')
+					p++;
+			}
+			VSB_cat(vsb, p);
+		}
+		VSB_cat(vsb, "\n");
+		free(strings);
+	}
+}
+
+void
+VBT_format(struct vsb *vsb)
+{
+
+#ifdef WITH_UNWIND
+	if (!vbt_unwind(vsb))
+		return;
+	VSB_cat(vsb, "Falling back to execinfo backtrace\n");
+#endif
+	vbt_execinfo(vsb);
+}


More information about the varnish-commit mailing list