Add backtrace support for debugging
authorJouni Malinen <j@w1.fi>
Sat, 19 Dec 2009 16:40:54 +0000 (18:40 +0200)
committerJouni Malinen <j@w1.fi>
Sat, 19 Dec 2009 16:40:54 +0000 (18:40 +0200)
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.

hostapd/Makefile
src/utils/Makefile
src/utils/eloop.c
src/utils/trace.c [new file with mode: 0644]
src/utils/trace.h [new file with mode: 0644]
wpa_supplicant/Makefile

index 4155a34..21b4a66 100644 (file)
@@ -48,6 +48,11 @@ OBJS += ../src/drivers/drivers.o
 OBJS += ../src/drivers/scan_helpers.o
 CFLAGS += -DHOSTAPD
 
+ifdef CONFIG_WPA_TRACE
+CFLAGS += -DWPA_TRACE
+OBJS += ../src/utils/trace.o
+endif
+
 OBJS += ../src/utils/eloop.o
 OBJS += ../src/utils/common.o
 OBJS += ../src/utils/wpa_debug.o
index bf9e444..7cb8dc1 100644 (file)
@@ -10,11 +10,14 @@ install:
 
 include ../lib.rules
 
+#CFLAGS += -DWPA_TRACE
+
 LIB_OBJS= \
        base64.o \
        common.o \
        ip_addr.o \
        radiotap.o \
+       trace.o \
        uuid.o \
        wpa_debug.o \
        wpabuf.o
index 4edb2a7..59fab99 100644 (file)
@@ -15,6 +15,7 @@
 #include "includes.h"
 
 #include "common.h"
+#include "trace.h"
 #include "eloop.h"
 
 
@@ -23,6 +24,7 @@ struct eloop_sock {
        void *eloop_data;
        void *user_data;
        eloop_sock_handler handler;
+       WPA_TRACE_INFO
 };
 
 struct eloop_timeout {
@@ -31,6 +33,7 @@ struct eloop_timeout {
        void *user_data;
        eloop_timeout_handler handler;
        struct eloop_timeout *next;
+       WPA_TRACE_INFO
 };
 
 struct eloop_signal {
@@ -69,10 +72,22 @@ struct eloop_data {
 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)
 {
        os_memset(&eloop, 0, sizeof(eloop));
        eloop.user_data = user_data;
+#ifdef WPA_TRACE
+       signal(SIGSEGV, eloop_sigsegv_handler);
+#endif /* WPA_TRACE */
        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].user_data = user_data;
        tmp[table->count].handler = handler;
+       wpa_trace_record(&tmp[table->count]);
        table->count++;
        table->table = tmp;
        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].user_data,
                               table->table[i].handler);
+                       wpa_trace_dump("eloop sock", &table->table[i]);
                }
                os_free(table->table);
        }
@@ -256,6 +273,7 @@ int eloop_register_timeout(unsigned int secs, unsigned int usecs,
        timeout->user_data = user_data;
        timeout->handler = handler;
        timeout->next = NULL;
+       wpa_trace_record(timeout);
 
        if (eloop.timeout == NULL) {
                eloop.timeout = timeout;
@@ -543,6 +561,7 @@ void eloop_destroy(void)
                       "user_data=%p handler=%p\n",
                       sec, usec, prev->eloop_data, prev->user_data,
                       prev->handler);
+               wpa_trace_dump("eloop timeout", prev);
                os_free(prev);
        }
        eloop_sock_table_destroy(&eloop.readers);
diff --git a/src/utils/trace.c b/src/utils/trace.c
new file mode 100644 (file)
index 0000000..1c4481d
--- /dev/null
@@ -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 */
diff --git a/src/utils/trace.h b/src/utils/trace.h
new file mode 100644 (file)
index 0000000..8074d25
--- /dev/null
@@ -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 */
index 1eb5b3b..6e3a8d5 100644 (file)
@@ -68,6 +68,11 @@ OBJS += ../src/utils/os_$(CONFIG_OS).o
 OBJS_p += ../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
 CONFIG_ELOOP=eloop
 endif