Add backtrace support for debugging

WPA_TRACE=y can now be used to enable internal backtrace support that
will provide more details about implementation errors, e.g., when some
resources are not released correctly. In addition, this will print out
a backtrace automatically if SIGSEGV is received.
This commit is contained in:
Jouni Malinen 2009-12-19 18:40:54 +02:00
parent f5d4a8ead4
commit 930f704aac
6 changed files with 118 additions and 0 deletions

View file

@ -48,6 +48,11 @@ OBJS += ../src/drivers/drivers.o
OBJS += ../src/drivers/scan_helpers.o OBJS += ../src/drivers/scan_helpers.o
CFLAGS += -DHOSTAPD CFLAGS += -DHOSTAPD
ifdef CONFIG_WPA_TRACE
CFLAGS += -DWPA_TRACE
OBJS += ../src/utils/trace.o
endif
OBJS += ../src/utils/eloop.o OBJS += ../src/utils/eloop.o
OBJS += ../src/utils/common.o OBJS += ../src/utils/common.o
OBJS += ../src/utils/wpa_debug.o OBJS += ../src/utils/wpa_debug.o

View file

@ -10,11 +10,14 @@ install:
include ../lib.rules include ../lib.rules
#CFLAGS += -DWPA_TRACE
LIB_OBJS= \ LIB_OBJS= \
base64.o \ base64.o \
common.o \ common.o \
ip_addr.o \ ip_addr.o \
radiotap.o \ radiotap.o \
trace.o \
uuid.o \ uuid.o \
wpa_debug.o \ wpa_debug.o \
wpabuf.o wpabuf.o

View file

@ -15,6 +15,7 @@
#include "includes.h" #include "includes.h"
#include "common.h" #include "common.h"
#include "trace.h"
#include "eloop.h" #include "eloop.h"
@ -23,6 +24,7 @@ struct eloop_sock {
void *eloop_data; void *eloop_data;
void *user_data; void *user_data;
eloop_sock_handler handler; eloop_sock_handler handler;
WPA_TRACE_INFO
}; };
struct eloop_timeout { struct eloop_timeout {
@ -31,6 +33,7 @@ struct eloop_timeout {
void *user_data; void *user_data;
eloop_timeout_handler handler; eloop_timeout_handler handler;
struct eloop_timeout *next; struct eloop_timeout *next;
WPA_TRACE_INFO
}; };
struct eloop_signal { struct eloop_signal {
@ -69,10 +72,22 @@ struct eloop_data {
static struct eloop_data eloop; static struct eloop_data eloop;
#ifdef WPA_TRACE
static void eloop_sigsegv_handler(int sig)
{
wpa_trace_show("eloop SIGSEGV");
abort();
}
#endif /* WPA_TRACE */
int eloop_init(void *user_data) int eloop_init(void *user_data)
{ {
os_memset(&eloop, 0, sizeof(eloop)); os_memset(&eloop, 0, sizeof(eloop));
eloop.user_data = user_data; eloop.user_data = user_data;
#ifdef WPA_TRACE
signal(SIGSEGV, eloop_sigsegv_handler);
#endif /* WPA_TRACE */
return 0; return 0;
} }
@ -96,6 +111,7 @@ static int eloop_sock_table_add_sock(struct eloop_sock_table *table,
tmp[table->count].eloop_data = eloop_data; tmp[table->count].eloop_data = eloop_data;
tmp[table->count].user_data = user_data; tmp[table->count].user_data = user_data;
tmp[table->count].handler = handler; tmp[table->count].handler = handler;
wpa_trace_record(&tmp[table->count]);
table->count++; table->count++;
table->table = tmp; table->table = tmp;
if (sock > eloop.max_sock) if (sock > eloop.max_sock)
@ -177,6 +193,7 @@ static void eloop_sock_table_destroy(struct eloop_sock_table *table)
table->table[i].eloop_data, table->table[i].eloop_data,
table->table[i].user_data, table->table[i].user_data,
table->table[i].handler); table->table[i].handler);
wpa_trace_dump("eloop sock", &table->table[i]);
} }
os_free(table->table); os_free(table->table);
} }
@ -256,6 +273,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
timeout->user_data = user_data; timeout->user_data = user_data;
timeout->handler = handler; timeout->handler = handler;
timeout->next = NULL; timeout->next = NULL;
wpa_trace_record(timeout);
if (eloop.timeout == NULL) { if (eloop.timeout == NULL) {
eloop.timeout = timeout; eloop.timeout = timeout;
@ -543,6 +561,7 @@ void eloop_destroy(void)
"user_data=%p handler=%p\n", "user_data=%p handler=%p\n",
sec, usec, prev->eloop_data, prev->user_data, sec, usec, prev->eloop_data, prev->user_data,
prev->handler); prev->handler);
wpa_trace_dump("eloop timeout", prev);
os_free(prev); os_free(prev);
} }
eloop_sock_table_destroy(&eloop.readers); eloop_sock_table_destroy(&eloop.readers);

46
src/utils/trace.c Normal file
View file

@ -0,0 +1,46 @@
/*
* Backtrace debugging
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#include "includes.h"
#include "common.h"
#include "trace.h"
#ifdef WPA_TRACE
void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num)
{
char **sym;
int i;
wpa_printf(MSG_INFO, "WPA_TRACE: %s - START", title);
sym = backtrace_symbols(btrace, btrace_num);
for (i = 0; i < btrace_num; i++)
wpa_printf(MSG_INFO, "[%d]: %p: %s",
i, btrace[i], sym ? sym[i] : "");
os_free(sym);
wpa_printf(MSG_INFO, "WPA_TRACE: %s - END", title);
}
void wpa_trace_show(const char *title)
{
struct info {
WPA_TRACE_INFO
} info;
wpa_trace_record(&info);
wpa_trace_dump(title, &info);
}
#endif /* WPA_TRACE */

40
src/utils/trace.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Backtrace debugging
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* Alternatively, this software may be distributed under the terms of BSD
* license.
*
* See README and COPYING for more details.
*/
#ifndef TRACE_H
#define TRACE_H
#define WPA_TRACE_LEN 16
#ifdef WPA_TRACE
#include <execinfo.h>
#define WPA_TRACE_INFO void *btrace[WPA_TRACE_LEN]; int btrace_num;
#define wpa_trace_dump(title, ptr) \
wpa_trace_dump_func((title), (ptr)->btrace, (ptr)->btrace_num)
void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num);
#define wpa_trace_record(ptr) \
(ptr)->btrace_num = backtrace((ptr)->btrace, WPA_TRACE_LEN)
void wpa_trace_show(const char *title);
#else /* WPA_TRACE */
#define WPA_TRACE_INFO
#define wpa_trace_dump(title, ptr) do { } while (0)
#define wpa_trace_record(ptr) do { } while (0)
#define wpa_trace_show(title) do { } while (0)
#endif /* WPA_TRACE */
#endif /* TRACE_H */

View file

@ -68,6 +68,11 @@ OBJS += ../src/utils/os_$(CONFIG_OS).o
OBJS_p += ../src/utils/os_$(CONFIG_OS).o OBJS_p += ../src/utils/os_$(CONFIG_OS).o
OBJS_c += ../src/utils/os_$(CONFIG_OS).o OBJS_c += ../src/utils/os_$(CONFIG_OS).o
ifdef CONFIG_WPA_TRACE
CFLAGS += -DWPA_TRACE
OBJS += ../src/utils/trace.o
endif
ifndef CONFIG_ELOOP ifndef CONFIG_ELOOP
CONFIG_ELOOP=eloop CONFIG_ELOOP=eloop
endif endif