Add support for simple glibc based backtrace

This commit is contained in:
Marcel Holtmann 2010-08-20 14:44:54 +02:00
parent 841d770988
commit df5d691c39
3 changed files with 110 additions and 1 deletions

View File

@ -310,8 +310,9 @@ doc_files = doc/overview.txt doc/ofono-paper.txt \
doc/supplementaryservices-api.txt \
doc/connman-api.txt
test_scripts = test/activate-context \
test_scripts = test/backtrace \
test/create-context \
test/activate-context \
test/deactivate-context \
test/dial-number \
test/disable-modem \

View File

@ -23,8 +23,12 @@
#include <config.h>
#endif
#define _GNU_SOURCE
#include <stdarg.h>
#include <syslog.h>
#include <stdlib.h>
#include <execinfo.h>
#include <dlfcn.h>
#include "ofono.h"
@ -103,6 +107,49 @@ void ofono_debug(const char *format, ...)
va_end(ap);
}
static void signal_handler(int signo)
{
void *frames[64];
char **symbols;
size_t n_ptrs;
unsigned int i;
n_ptrs = backtrace(frames, G_N_ELEMENTS(frames));
symbols = backtrace_symbols(frames, n_ptrs);
if (symbols == NULL) {
ofono_error("No backtrace symbols");
exit(1);
}
ofono_error("Aborting (signal %d)", signo);
ofono_error("++++++++ backtrace ++++++++");
for (i = 1; i < n_ptrs; i++)
ofono_error("[%d]: %s", i - 1, symbols[i]);
ofono_error("+++++++++++++++++++++++++++");
g_free(symbols);
exit(1);
}
static void signal_setup(sighandler_t handler)
{
struct sigaction sa;
sigset_t mask;
sigemptyset(&mask);
sa.sa_handler = handler;
sa.sa_mask = mask;
sa.sa_flags = 0;
sigaction(SIGBUS, &sa, NULL);
sigaction(SIGILL, &sa, NULL);
sigaction(SIGFPE, &sa, NULL);
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
sigaction(SIGPIPE, &sa, NULL);
}
extern struct ofono_debug_desc __start___debug[];
extern struct ofono_debug_desc __stop___debug[];
@ -152,6 +199,8 @@ int __ofono_log_init(const char *debug, ofono_bool_t detach)
if (detach == FALSE)
option |= LOG_PERROR;
signal_setup(signal_handler);
openlog("ofonod", option, LOG_DAEMON);
syslog(LOG_INFO, "oFono version %s", VERSION);
@ -165,5 +214,7 @@ void __ofono_log_cleanup(void)
closelog();
signal_setup(SIG_DFL);
g_strfreev(enabled);
}

57
test/backtrace Executable file
View File

@ -0,0 +1,57 @@
#!/usr/bin/python
import os
import re
import sys
import subprocess
if (len(sys.argv) < 3):
print "Usage: %s [binary] [log]" % (sys.argv[0])
sys.exit(1)
binary = sys.argv[1]
count = 0
frames = []
addrs = []
log_file = open(sys.argv[2], 'r')
# Extract addresses
for line in log_file:
matchobj = re.compile(r'\[(0x[0-9a-f]+)\]$').search(line)
if matchobj:
addrs.append(matchobj.group(1))
log_file.close()
# Feed into addr2line
command = ['addr2line', '--demangle', '--functions', '--basename',
'-e', binary]
command.extend(addrs)
p = subprocess.Popen(command, shell=False, bufsize=0,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, close_fds=True)
(child_stdin, child_stdout) = (p.stdin, p.stdout)
child_stdin.close()
# Backtrace display
for line in child_stdout:
if line.startswith("??"):
continue
line = line.strip()
frames.append(line)
child_stdout.close()
frame_count = len(frames);
count = 0
print "-------- backtrace --------"
while count < frame_count:
print "[%d]: %s() [%s]" % (count/2, frames[count], frames[count + 1])
count = count + 2
print "---------------------------"