|
Packit |
34410b |
/*
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
* BlueZ - Bluetooth protocol stack for Linux
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
* Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
34410b |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
34410b |
* the Free Software Foundation; either version 2 of the License, or
|
|
Packit |
34410b |
* (at your option) any later version.
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
34410b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
34410b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
34410b |
* GNU General Public License for more details.
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
* You should have received a copy of the GNU General Public License
|
|
Packit |
34410b |
* along with this program; if not, write to the Free Software
|
|
Packit |
34410b |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit |
34410b |
*
|
|
Packit |
34410b |
*/
|
|
Packit |
34410b |
|
|
Packit |
34410b |
#ifdef HAVE_CONFIG_H
|
|
Packit |
34410b |
#include <config.h>
|
|
Packit |
34410b |
#endif
|
|
Packit |
34410b |
|
|
Packit |
34410b |
#include <unistd.h>
|
|
Packit |
34410b |
#include <inttypes.h>
|
|
Packit |
34410b |
|
|
Packit |
34410b |
#ifdef HAVE_BACKTRACE_SUPPORT
|
|
Packit |
34410b |
#include <execinfo.h>
|
|
Packit |
34410b |
#include <elfutils/libdwfl.h>
|
|
Packit |
34410b |
#endif
|
|
Packit |
34410b |
|
|
Packit |
34410b |
#include "src/log.h"
|
|
Packit |
34410b |
#include "src/backtrace.h"
|
|
Packit |
34410b |
|
|
Packit |
34410b |
void btd_backtrace_init(void)
|
|
Packit |
34410b |
{
|
|
Packit |
34410b |
#ifdef HAVE_BACKTRACE_SUPPORT
|
|
Packit |
34410b |
void *frames[1];
|
|
Packit |
34410b |
|
|
Packit |
34410b |
/*
|
|
Packit |
34410b |
* initialize the backtracer, since the ctor calls dlopen(), which
|
|
Packit |
34410b |
* calls malloc(), which isn't signal-safe.
|
|
Packit |
34410b |
*/
|
|
Packit |
34410b |
backtrace(frames, 1);
|
|
Packit |
34410b |
#endif
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
|
|
Packit |
34410b |
void btd_backtrace(uint16_t index)
|
|
Packit |
34410b |
{
|
|
Packit |
34410b |
#ifdef HAVE_BACKTRACE_SUPPORT
|
|
Packit |
34410b |
char *debuginfo_path = NULL;
|
|
Packit |
34410b |
const Dwfl_Callbacks callbacks = {
|
|
Packit |
34410b |
.find_debuginfo = dwfl_standard_find_debuginfo,
|
|
Packit |
34410b |
.find_elf = dwfl_linux_proc_find_elf,
|
|
Packit |
34410b |
.debuginfo_path = &debuginfo_path,
|
|
Packit |
34410b |
};
|
|
Packit |
34410b |
Dwfl *dwfl;
|
|
Packit |
34410b |
void *frames[48];
|
|
Packit |
34410b |
int n, n_ptrs;
|
|
Packit |
34410b |
|
|
Packit |
34410b |
dwfl = dwfl_begin(&callbacks);
|
|
Packit |
34410b |
|
|
Packit |
34410b |
if (dwfl_linux_proc_report(dwfl, getpid()))
|
|
Packit |
34410b |
goto done;
|
|
Packit |
34410b |
|
|
Packit |
34410b |
dwfl_report_end(dwfl, NULL, NULL);
|
|
Packit |
34410b |
|
|
Packit |
34410b |
n_ptrs = backtrace(frames, 48);
|
|
Packit |
34410b |
if (n_ptrs < 1)
|
|
Packit |
34410b |
goto done;
|
|
Packit |
34410b |
|
|
Packit |
34410b |
btd_error(index, "++++++++ backtrace ++++++++");
|
|
Packit |
34410b |
|
|
Packit |
34410b |
for (n = 1; n < n_ptrs; n++) {
|
|
Packit |
34410b |
GElf_Addr addr = (uintptr_t) frames[n];
|
|
Packit |
34410b |
GElf_Sym sym;
|
|
Packit |
34410b |
GElf_Word shndx;
|
|
Packit |
34410b |
Dwfl_Module *module = dwfl_addrmodule(dwfl, addr);
|
|
Packit |
34410b |
Dwfl_Line *line;
|
|
Packit |
34410b |
const char *name, *modname;
|
|
Packit |
34410b |
|
|
Packit |
34410b |
if (!module) {
|
|
Packit |
34410b |
btd_error(index, "#%-2u ?? [%#" PRIx64 "]", n, addr);
|
|
Packit |
34410b |
continue;
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
|
|
Packit |
34410b |
name = dwfl_module_addrsym(module, addr, &sym, &shndx);
|
|
Packit |
34410b |
if (!name) {
|
|
Packit |
34410b |
modname = dwfl_module_info(module, NULL, NULL, NULL,
|
|
Packit |
34410b |
NULL, NULL, NULL, NULL);
|
|
Packit |
34410b |
btd_error(index, "#%-2u ?? (%s) [%#" PRIx64 "]",
|
|
Packit |
34410b |
n, modname, addr);
|
|
Packit |
34410b |
continue;
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
|
|
Packit |
34410b |
line = dwfl_module_getsrc(module, addr);
|
|
Packit |
34410b |
if (line) {
|
|
Packit |
34410b |
int lineno;
|
|
Packit |
34410b |
const char *src = dwfl_lineinfo(line, NULL, &lineno,
|
|
Packit |
34410b |
NULL, NULL, NULL);
|
|
Packit |
34410b |
|
|
Packit |
34410b |
if (src) {
|
|
Packit |
34410b |
btd_error(index, "#%-2u %s+%#" PRIx64 " "
|
|
Packit |
34410b |
"(%s:%d) [%#" PRIx64 "]",
|
|
Packit |
34410b |
n, name, addr - sym.st_value,
|
|
Packit |
34410b |
src, lineno, addr);
|
|
Packit |
34410b |
continue;
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
|
|
Packit |
34410b |
modname = dwfl_module_info(module, NULL, NULL, NULL,
|
|
Packit |
34410b |
NULL, NULL, NULL, NULL);
|
|
Packit |
34410b |
btd_error(index, "#%-2u %s+%#" PRIx64 " (%s) [%#" PRIx64 "]",
|
|
Packit |
34410b |
n, name, addr - sym.st_value,
|
|
Packit |
34410b |
modname, addr);
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
|
|
Packit |
34410b |
btd_error(index, "+++++++++++++++++++++++++++");
|
|
Packit |
34410b |
|
|
Packit |
34410b |
done:
|
|
Packit |
34410b |
dwfl_end(dwfl);
|
|
Packit |
34410b |
#endif
|
|
Packit |
34410b |
}
|
|
Packit |
34410b |
|
|
Packit |
34410b |
void btd_assertion_message_expr(const char *file, int line,
|
|
Packit |
34410b |
const char *func, const char *expr)
|
|
Packit |
34410b |
{
|
|
Packit |
34410b |
btd_error(0xffff, "Assertion failed: (%s) %s:%d in %s",
|
|
Packit |
34410b |
expr, file, line, func);
|
|
Packit |
34410b |
btd_backtrace(0xffff);
|
|
Packit |
34410b |
}
|