diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2015-11-08 14:44:24 +0100 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2015-11-08 14:44:24 +0100 |
commit | 16669134e166a993bd76aa24222226300d4f3df6 (patch) | |
tree | d81c17c989e46302bb79b44ce829db32343497b9 | |
parent | 410f228247bfe10d99798acb08c22ba3470662d9 (diff) | |
download | bluez-16669134e166a993bd76aa24222226300d4f3df6.tar.gz |
core: Add support for basic stack backtrace helper
-rw-r--r-- | Makefile.am | 3 | ||||
-rwxr-xr-x | bootstrap-configure | 1 | ||||
-rw-r--r-- | configure.ac | 14 | ||||
-rw-r--r-- | src/backtrace.c | 124 | ||||
-rw-r--r-- | src/backtrace.h | 34 |
5 files changed, 175 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am index 356f650a3..614922e16 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 29cd7bf44..87766b117 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 2d3e5d716..5c398c5db 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 000000000..938025b45 --- /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 000000000..654d67d37 --- /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) |