From 4f68895e923fea3c5aefcca0ae75aa06ac698b9c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 31 Mar 2012 13:55:33 +0300 Subject: debug: Add option to log to Linux tracing Add the option (-T) to wpa_supplicant to log all debug messages into the kernel tracing, allowing to aggregate kernel debugging with wpa_supplicant debugging and recording all with trace-cmd. Since tracing has relatively low overhead and can be filtered afterwards, record all messages regardless of log level. However, it will honor the -K option and not record key material by default. Signed-hostap: Johannes Berg --- src/utils/wpa_debug.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/utils/wpa_debug.h | 18 +++++++ 2 files changed, 150 insertions(+) (limited to 'src/utils') diff --git a/src/utils/wpa_debug.c b/src/utils/wpa_debug.c index 858a97c..3b71d10 100644 --- a/src/utils/wpa_debug.c +++ b/src/utils/wpa_debug.c @@ -16,6 +16,18 @@ static int wpa_debug_syslog = 0; #endif /* CONFIG_DEBUG_SYSLOG */ +#ifdef CONFIG_DEBUG_LINUX_TRACING +#include +#include +#include +#include +#include + +static FILE *wpa_debug_tracing_file = NULL; + +#define WPAS_TRACE_PFX "wpas <%d>: " +#endif /* CONFIG_DEBUG_LINUX_TRACING */ + int wpa_debug_level = MSG_INFO; int wpa_debug_show_keys = 0; @@ -107,6 +119,77 @@ static int syslog_priority(int level) #endif /* CONFIG_DEBUG_SYSLOG */ +#ifdef CONFIG_DEBUG_LINUX_TRACING + +int wpa_debug_open_linux_tracing(void) +{ + int mounts, trace_fd; + char buf[4096] = {}; + ssize_t buflen; + char *line, *tmp1, *path = NULL; + + mounts = open("/proc/mounts", O_RDONLY); + if (mounts < 0) { + printf("no /proc/mounts\n"); + return -1; + } + + buflen = read(mounts, buf, sizeof(buf) - 1); + close(mounts); + if (buflen < 0) { + printf("failed to read /proc/mounts\n"); + return -1; + } + + line = strtok_r(buf, "\n", &tmp1); + while (line) { + char *tmp2, *tmp_path, *fstype; + /* " ..." */ + strtok_r(line, " ", &tmp2); + tmp_path = strtok_r(NULL, " ", &tmp2); + fstype = strtok_r(NULL, " ", &tmp2); + if (strcmp(fstype, "debugfs") == 0) { + path = tmp_path; + break; + } + + line = strtok_r(NULL, "\n", &tmp1); + } + + if (path == NULL) { + printf("debugfs mountpoint not found\n"); + return -1; + } + + snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path); + + trace_fd = open(buf, O_WRONLY); + if (trace_fd < 0) { + printf("failed to open trace_marker file\n"); + return -1; + } + wpa_debug_tracing_file = fdopen(trace_fd, "w"); + if (wpa_debug_tracing_file == NULL) { + close(trace_fd); + printf("failed to fdopen()\n"); + return -1; + } + + return 0; +} + + +void wpa_debug_close_linux_tracing(void) +{ + if (wpa_debug_tracing_file == NULL) + return; + fclose(wpa_debug_tracing_file); + wpa_debug_tracing_file = NULL; +} + +#endif /* CONFIG_DEBUG_LINUX_TRACING */ + + /** * wpa_printf - conditional printf * @level: priority level (MSG_*) of the message @@ -151,6 +234,17 @@ void wpa_printf(int level, const char *fmt, ...) #endif /* CONFIG_ANDROID_LOG */ } va_end(ap); + +#ifdef CONFIG_DEBUG_LINUX_TRACING + if (wpa_debug_tracing_file != NULL) { + va_start(ap, fmt); + fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level); + vfprintf(wpa_debug_tracing_file, fmt, ap); + fprintf(wpa_debug_tracing_file, "\n"); + fflush(wpa_debug_tracing_file); + va_end(ap); + } +#endif /* CONFIG_DEBUG_LINUX_TRACING */ } @@ -158,6 +252,25 @@ static void _wpa_hexdump(int level, const char *title, const u8 *buf, size_t len, int show) { size_t i; + +#ifdef CONFIG_DEBUG_LINUX_TRACING + if (wpa_debug_tracing_file != NULL) { + fprintf(wpa_debug_tracing_file, + WPAS_TRACE_PFX "%s - hexdump(len=%lu):", + level, title, (unsigned long) len); + if (buf == NULL) { + fprintf(wpa_debug_tracing_file, " [NULL]\n"); + } else if (!show) { + fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); + } else { + for (i = 0; i < len; i++) + fprintf(wpa_debug_tracing_file, + " %02x", buf[i]); + } + fflush(wpa_debug_tracing_file); + } +#endif /* CONFIG_DEBUG_LINUX_TRACING */ + if (level < wpa_debug_level) return; #ifdef CONFIG_ANDROID_LOG @@ -281,6 +394,25 @@ static void _wpa_hexdump_ascii(int level, const char *title, const u8 *buf, const u8 *pos = buf; const size_t line_len = 16; +#ifdef CONFIG_DEBUG_LINUX_TRACING + if (wpa_debug_tracing_file != NULL) { + fprintf(wpa_debug_tracing_file, + WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):", + level, title, (unsigned long) len); + if (buf == NULL) { + fprintf(wpa_debug_tracing_file, " [NULL]\n"); + } else if (!show) { + fprintf(wpa_debug_tracing_file, " [REMOVED]\n"); + } else { + /* can do ascii processing in userspace */ + for (i = 0; i < len; i++) + fprintf(wpa_debug_tracing_file, + " %02x", buf[i]); + } + fflush(wpa_debug_tracing_file); + } +#endif /* CONFIG_DEBUG_LINUX_TRACING */ + if (level < wpa_debug_level) return; #ifdef CONFIG_ANDROID_LOG diff --git a/src/utils/wpa_debug.h b/src/utils/wpa_debug.h index c79907a..339c749 100644 --- a/src/utils/wpa_debug.h +++ b/src/utils/wpa_debug.h @@ -255,6 +255,24 @@ static inline void wpa_debug_close_syslog(void) #endif /* CONFIG_DEBUG_SYSLOG */ +#ifdef CONFIG_DEBUG_LINUX_TRACING + +int wpa_debug_open_linux_tracing(void); +void wpa_debug_close_linux_tracing(void); + +#else /* CONFIG_DEBUG_LINUX_TRACING */ + +static inline int wpa_debug_open_linux_tracing(void) +{ + return 0; +} + +static inline void wpa_debug_close_linux_tracing(void) +{ +} + +#endif /* CONFIG_DEBUG_LINUX_TRACING */ + #ifdef EAPOL_TEST #define WPA_ASSERT(a) \ -- cgit v1.1