Diff between 410f228247bfe10d99798acb08c22ba3470662d9 and 16669134e166a993bd76aa24222226300d4f3df6

Changed Files

File Additions Deletions Status
Makefile.am +2 -1 modified
bootstrap-configure +1 -0 modified
configure.ac +14 -0 modified
src/backtrace.c +124 -0 added
src/backtrace.h +34 -0 added

Full Patch

diff --git a/Makefile.am b/Makefile.am
index 356f650..614922e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -163,6 +163,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
 			$(attrib_sources) $(btio_sources) \
 			src/bluetooth.ver \
 			src/main.c src/log.h src/log.c \
+			src/backtrace.h src/backtrace.c \
 			src/systemd.h src/systemd.c \
 			src/rfkill.c src/hcid.h src/sdpd.h \
 			src/sdpd-server.c src/sdpd-request.c \
@@ -189,7 +190,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
 src_bluetoothd_LDADD = lib/libbluetooth-internal.la \
 			gdbus/libgdbus-internal.la \
 			src/libshared-glib.la \
-			@GLIB_LIBS@ @DBUS_LIBS@ -ldl -lrt
+			@BACKTRACE_LIBS@ @GLIB_LIBS@ @DBUS_LIBS@ -ldl -lrt
 src_bluetoothd_LDFLAGS = $(AM_LDFLAGS) -Wl,--export-dynamic \
 				-Wl,--version-script=$(srcdir)/src/bluetooth.ver
 
diff --git a/bootstrap-configure b/bootstrap-configure
index 29cd7bf..87766b1 100755
--- a/bootstrap-configure
+++ b/bootstrap-configure
@@ -12,6 +12,7 @@ fi
 		--sysconfdir=/etc \
 		--localstatedir=/var \
 		--enable-manpages \
+		--enable-backtrace \
 		--enable-experimental \
 		--enable-android \
 		--enable-sixaxis \
diff --git a/configure.ac b/configure.ac
index 2d3e5d7..5c398c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -118,6 +118,20 @@ if (test -z "${path_dbussessionbusdir}"); then
 fi
 AC_SUBST(DBUS_SESSIONBUSDIR, [${path_dbussessionbusdir}])
 
+AC_ARG_ENABLE(backtrace, AC_HELP_STRING([--enable-backtrace],
+		[compile backtrace support]), [enable_backtrace=${enableval}])
+
+if (test "${enable_backtrace}" = "yes"); then
+	AC_CHECK_HEADER(elfutils/libdwfl.h, dummy=yes,
+			AC_MSG_ERROR(elfutils support is required))
+	AC_DEFINE(HAVE_BACKTRACE_SUPPORT, 1,
+			[Define to 1 if you have the backtrace support.])
+	BACKTRACE_CFLAGS=""
+	BACKTRACE_LIBS="-ldw"
+	AC_SUBST(BACKTRACE_CFLAGS)
+	AC_SUBST(BACKTRACE_LIBS)
+fi
+
 AC_ARG_ENABLE(library, AC_HELP_STRING([--enable-library],
 		[install Bluetooth library]), [enable_library=${enableval}])
 AM_CONDITIONAL(LIBRARY, test "${enable_library}" = "yes")
diff --git a/src/backtrace.c b/src/backtrace.c
new file mode 100644
index 0000000..938025b
--- /dev/null
+++ b/src/backtrace.c
@@ -0,0 +1,124 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <inttypes.h>
+
+#include "src/log.h"
+#include "src/backtrace.h"
+
+#ifdef HAVE_BACKTRACE_SUPPORT
+#include <execinfo.h>
+#include <elfutils/libdwfl.h>
+
+void btd_backtrace(uint16_t index)
+{
+	char *debuginfo_path = NULL;
+	const Dwfl_Callbacks callbacks = {
+		.find_debuginfo = dwfl_standard_find_debuginfo,
+		.find_elf = dwfl_linux_proc_find_elf,
+		.debuginfo_path = &debuginfo_path,
+	};
+	Dwfl *dwfl;
+	void *frames[48];
+	int n, n_ptrs;
+
+	dwfl = dwfl_begin(&callbacks);
+
+	if (dwfl_linux_proc_report(dwfl, getpid()))
+		goto done;
+
+	dwfl_report_end(dwfl, NULL, NULL);
+
+	n_ptrs = backtrace(frames, 48);
+	if (n_ptrs < 1)
+		goto done;
+
+	btd_error(index, "++++++++ backtrace ++++++++");
+
+	for (n = 1; n < n_ptrs; n++) {
+		GElf_Addr addr = (uintptr_t) frames[n];
+		GElf_Sym sym;
+		GElf_Word shndx;
+		Dwfl_Module *module = dwfl_addrmodule(dwfl, addr);
+		Dwfl_Line *line;
+		const char *name, *modname;
+
+		if (!module) {
+			btd_error(index, "#%-2u ?? [%#" PRIx64 "]", n, addr);
+			continue;
+		}
+
+		name = dwfl_module_addrsym(module, addr, &sym, &shndx);
+		if (!name) {
+			modname = dwfl_module_info(module, NULL, NULL, NULL,
+							NULL, NULL, NULL, NULL);
+			btd_error(index, "#%-2u ?? (%s) [%#" PRIx64 "]",
+							n, modname, addr);
+			continue;
+		}
+
+		line = dwfl_module_getsrc(module, addr);
+		if (line) {
+			int lineno;
+			const char *src = dwfl_lineinfo(line, NULL, &lineno,
+							NULL, NULL, NULL);
+
+			if (src) {
+				btd_error(index, "#%-2u %s+%#" PRIx64 " "
+						"(%s:%d) [%#" PRIx64 "]",
+						n, name, addr - sym.st_value,
+							src, lineno, addr);
+				continue;
+			}
+		}
+
+		modname = dwfl_module_info(module, NULL, NULL, NULL,
+						NULL, NULL, NULL, NULL);
+		btd_error(index, "#%-2u %s+%#" PRIx64 " (%s) [%#" PRIx64 "]",
+						n, name, addr - sym.st_value,
+								modname, addr);
+	}
+
+	btd_error(index, "+++++++++++++++++++++++++++");
+
+done:
+	dwfl_end(dwfl);
+}
+#else
+void btd_backtrace(uint16_t index)
+{
+}
+#endif
+
+void btd_assertion_message_expr(const char *file, int line,
+					const char *func, const char *expr)
+{
+	btd_error(0xffff, "Assertion failed: (%s) %s:%d in %s",
+						expr, file, line, func);
+	btd_backtrace(0xffff);
+}
diff --git a/src/backtrace.h b/src/backtrace.h
new file mode 100644
index 0000000..654d67d
--- /dev/null
+++ b/src/backtrace.h
@@ -0,0 +1,34 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdint.h>
+
+void btd_backtrace(uint16_t index);
+
+void btd_assertion_message_expr(const char *file, int line,
+					const char *func, const char *expr);
+
+#define btd_assert(expr) do { \
+	if (expr) ; else \
+		btd_assertion_message_expr(__FILE__, __LINE__, __func__, #expr); \
+	} while (0)