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:
parent
f5d4a8ead4
commit
930f704aac
6 changed files with 118 additions and 0 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
46
src/utils/trace.c
Normal 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
40
src/utils/trace.h
Normal 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 */
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue