From: Benjamin Berg <benjamin.berg@xxxxxxxxx> Refactor the backtrace matching a bit in order to allow triggering multiple failures in one test. Signed-off-by: Benjamin Berg <benjamin.berg@xxxxxxxxx> --- hostapd/ctrl_iface.c | 77 +--------------- src/utils/os.h | 20 +++-- src/utils/os_unix.c | 170 ++++++++++++++++-------------------- wpa_supplicant/ctrl_iface.c | 74 +--------------- 4 files changed, 98 insertions(+), 243 deletions(-) diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 6ad86142e6..8d34cf1627 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -2006,74 +2006,6 @@ done: } -static int hostapd_ctrl_test_alloc_fail(struct hostapd_data *hapd, char *cmd) -{ -#ifdef WPA_TRACE_BFD - char *pos; - - wpa_trace_fail_after = atoi(cmd); - pos = os_strchr(cmd, ':'); - if (pos) { - pos++; - os_strlcpy(wpa_trace_fail_func, pos, - sizeof(wpa_trace_fail_func)); - } else { - wpa_trace_fail_after = 0; - } - - return 0; -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - -static int hostapd_ctrl_get_alloc_fail(struct hostapd_data *hapd, - char *buf, size_t buflen) -{ -#ifdef WPA_TRACE_BFD - return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after, - wpa_trace_fail_func); -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - -static int hostapd_ctrl_test_fail(struct hostapd_data *hapd, char *cmd) -{ -#ifdef WPA_TRACE_BFD - char *pos; - - wpa_trace_test_fail_after = atoi(cmd); - pos = os_strchr(cmd, ':'); - if (pos) { - pos++; - os_strlcpy(wpa_trace_test_fail_func, pos, - sizeof(wpa_trace_test_fail_func)); - } else { - wpa_trace_test_fail_after = 0; - } - - return 0; -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - -static int hostapd_ctrl_get_fail(struct hostapd_data *hapd, - char *buf, size_t buflen) -{ -#ifdef WPA_TRACE_BFD - return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after, - wpa_trace_test_fail_func); -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - static int hostapd_ctrl_reset_pn(struct hostapd_data *hapd, const char *cmd) { struct sta_info *sta; @@ -3704,16 +3636,15 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd, if (hostapd_ctrl_iface_data_test_frame(hapd, buf + 16) < 0) reply_len = -1; } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) { - if (hostapd_ctrl_test_alloc_fail(hapd, buf + 16) < 0) + if (testing_set_fail_pattern(true, buf + 16) < 0) reply_len = -1; } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) { - reply_len = hostapd_ctrl_get_alloc_fail(hapd, reply, - reply_size); + reply_len = testing_get_fail_pattern(true, reply, reply_size); } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) { - if (hostapd_ctrl_test_fail(hapd, buf + 10) < 0) + if (testing_set_fail_pattern(false, buf + 10) < 0) reply_len = -1; } else if (os_strcmp(buf, "GET_FAIL") == 0) { - reply_len = hostapd_ctrl_get_fail(hapd, reply, reply_size); + reply_len = testing_get_fail_pattern(false, reply, reply_size); } else if (os_strncmp(buf, "RESET_PN ", 9) == 0) { if (hostapd_ctrl_reset_pn(hapd, buf + 9) < 0) reply_len = -1; diff --git a/src/utils/os.h b/src/utils/os.h index 21ba5c3ff8..83d5ad99b2 100644 --- a/src/utils/os.h +++ b/src/utils/os.h @@ -667,14 +667,22 @@ int os_exec(const char *program, const char *arg, int wait_completion); #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) -#define TEST_FAIL() testing_test_fail() -int testing_test_fail(void); -extern char wpa_trace_fail_func[256]; -extern unsigned int wpa_trace_fail_after; -extern char wpa_trace_test_fail_func[256]; -extern unsigned int wpa_trace_test_fail_after; +#define TEST_FAIL() testing_test_fail(false) +int testing_test_fail(bool is_alloc); +int testing_set_fail_pattern(bool is_alloc, char *patterns); +int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen); #else #define TEST_FAIL() 0 +static inline int testing_set_fail_pattern(bool is_alloc, char *patterns) +{ + return -1; +} + +static inline int testing_get_fail_pattern(bool is_alloc, char *buf, + size_t buflen) +{ + return -1; +} #endif #endif /* OS_H */ diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c index 258deef9dd..d9664b0f79 100644 --- a/src/utils/os_unix.c +++ b/src/utils/os_unix.c @@ -540,39 +540,46 @@ void * os_memdup(const void *src, size_t len) #ifdef WPA_TRACE #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) -char wpa_trace_fail_func[256] = { 0 }; -unsigned int wpa_trace_fail_after; +struct wpa_trace_test_fail { + unsigned int fail_after; + char pattern[256]; +} wpa_trace_test_fail[5][2]; -static int testing_fail_alloc(void) +int testing_test_fail(bool is_alloc) { + const char *ignore_list[] = { + __func__, "os_malloc", "os_zalloc", "os_calloc", "os_realloc", + "os_realloc_array", "os_strdup", "os_memdup" + }; const char *func[WPA_TRACE_LEN]; - size_t i, res, len; + size_t i, j, res, len, idx; char *pos, *next; int match; - if (!wpa_trace_fail_after) + is_alloc = !!is_alloc; + + for (idx = 0; idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc]); idx++) { + if (wpa_trace_test_fail[is_alloc][idx].fail_after != 0) + break; + } + if (idx >= ARRAY_SIZE(wpa_trace_test_fail[is_alloc])) return 0; res = wpa_trace_calling_func(func, WPA_TRACE_LEN); i = 0; - if (i < res && os_strcmp(func[i], __func__) == 0) - i++; - if (i < res && os_strcmp(func[i], "os_malloc") == 0) - i++; - if (i < res && os_strcmp(func[i], "os_zalloc") == 0) - i++; - if (i < res && os_strcmp(func[i], "os_calloc") == 0) - i++; - if (i < res && os_strcmp(func[i], "os_realloc") == 0) - i++; - if (i < res && os_strcmp(func[i], "os_realloc_array") == 0) - i++; - if (i < res && os_strcmp(func[i], "os_strdup") == 0) - i++; - if (i < res && os_strcmp(func[i], "os_memdup") == 0) - i++; - pos = wpa_trace_fail_func; + /* Skip this function as well as allocation helpers */ + for (j = 0; j < ARRAY_SIZE(ignore_list) && i < res; j++) { + if (os_strcmp(func[i], ignore_list[j]) == 0) + i++; + } + + pos = wpa_trace_test_fail[is_alloc][idx].pattern; + + /* The prefixes mean: + * - '=': The function needs to be next in the backtrace + * - '?': The function is optionally present in the backtrace + */ match = 0; while (i < res) { @@ -612,10 +619,10 @@ static int testing_fail_alloc(void) if (!match) return 0; - wpa_trace_fail_after--; - if (wpa_trace_fail_after == 0) { - wpa_printf(MSG_INFO, "TESTING: fail allocation at %s", - wpa_trace_fail_func); + wpa_trace_test_fail[is_alloc][idx].fail_after--; + if (wpa_trace_test_fail[is_alloc][idx].fail_after == 0) { + wpa_printf(MSG_INFO, "TESTING: fail at %s", + wpa_trace_test_fail[is_alloc][idx].pattern); for (i = 0; i < res; i++) wpa_printf(MSG_INFO, "backtrace[%d] = %s", (int) i, func[i]); @@ -625,83 +632,58 @@ static int testing_fail_alloc(void) return 0; } - -char wpa_trace_test_fail_func[256] = { 0 }; -unsigned int wpa_trace_test_fail_after; - -int testing_test_fail(void) +int testing_set_fail_pattern(bool is_alloc, char *patterns) { - const char *func[WPA_TRACE_LEN]; - size_t i, res, len; - char *pos, *next; - int match; + char *token, *context = NULL; + size_t idx; + + is_alloc = !!is_alloc; + + os_memset(wpa_trace_test_fail[is_alloc], 0, + sizeof(wpa_trace_test_fail[is_alloc])); + + idx = 0; + while ((token = str_token(patterns, " \n\r\t", &context)) && + idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc])) { + wpa_trace_test_fail[is_alloc][idx].fail_after = atoi(token); + token = os_strchr(token, ':'); + if (!token) { + os_memset(wpa_trace_test_fail[is_alloc], 0, + sizeof(wpa_trace_test_fail[is_alloc])); + return -1; + } - if (!wpa_trace_test_fail_after) - return 0; + os_strlcpy(wpa_trace_test_fail[is_alloc][idx].pattern, + token + 1, + sizeof(wpa_trace_test_fail[is_alloc][0].pattern)); + idx++; + } - res = wpa_trace_calling_func(func, WPA_TRACE_LEN); - i = 0; - if (i < res && os_strcmp(func[i], __func__) == 0) - i++; + return 0; +} - pos = wpa_trace_test_fail_func; +int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen) +{ + size_t idx, ret; + char *pos = buf; + char *end = buf + buflen; - match = 0; - while (i < res) { - int allow_skip = 1; - int maybe = 0; + is_alloc = !!is_alloc; - if (*pos == '=') { - allow_skip = 0; - pos++; - } else if (*pos == '?') { - maybe = 1; - pos++; - } - next = os_strchr(pos, ';'); - if (next) - len = next - pos; - else - len = os_strlen(pos); - if (os_memcmp(pos, func[i], len) != 0) { - if (maybe && next) { - pos = next + 1; - continue; - } - if (allow_skip) { - i++; - continue; - } - return 0; - } - if (!next) { - match = 1; + for (idx = 0; idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc]); idx++) { + if (wpa_trace_test_fail[is_alloc][idx].pattern[0] == '\0') break; - } - pos = next + 1; - i++; - } - if (!match) - return 0; - wpa_trace_test_fail_after--; - if (wpa_trace_test_fail_after == 0) { - wpa_printf(MSG_INFO, "TESTING: fail at %s", - wpa_trace_test_fail_func); - for (i = 0; i < res; i++) - wpa_printf(MSG_INFO, "backtrace[%d] = %s", - (int) i, func[i]); - return 1; + ret = os_snprintf(pos, end - pos, "%s%u:%s", + pos == buf ? "" : " ", + wpa_trace_test_fail[is_alloc][idx].fail_after, + wpa_trace_test_fail[is_alloc][idx].pattern); + if (os_snprintf_error(end - pos, ret)) + break; + pos += ret; } - return 0; -} - -#else - -static inline int testing_fail_alloc(void) -{ - return 0; + return pos - buf; } #endif @@ -709,7 +691,7 @@ void * os_malloc(size_t size) { struct os_alloc_trace *a; - if (testing_fail_alloc()) + if (testing_test_fail(true)) return NULL; a = malloc(sizeof(*a) + size); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index a68802e493..b716fa774e 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -10134,72 +10134,6 @@ done: } -static int wpas_ctrl_test_alloc_fail(struct wpa_supplicant *wpa_s, char *cmd) -{ -#ifdef WPA_TRACE_BFD - char *pos; - - wpa_trace_fail_after = atoi(cmd); - pos = os_strchr(cmd, ':'); - if (pos) { - pos++; - os_strlcpy(wpa_trace_fail_func, pos, - sizeof(wpa_trace_fail_func)); - } else { - wpa_trace_fail_after = 0; - } - return 0; -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - -static int wpas_ctrl_get_alloc_fail(struct wpa_supplicant *wpa_s, - char *buf, size_t buflen) -{ -#ifdef WPA_TRACE_BFD - return os_snprintf(buf, buflen, "%u:%s", wpa_trace_fail_after, - wpa_trace_fail_func); -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - -static int wpas_ctrl_test_fail(struct wpa_supplicant *wpa_s, char *cmd) -{ -#ifdef WPA_TRACE_BFD - char *pos; - - wpa_trace_test_fail_after = atoi(cmd); - pos = os_strchr(cmd, ':'); - if (pos) { - pos++; - os_strlcpy(wpa_trace_test_fail_func, pos, - sizeof(wpa_trace_test_fail_func)); - } else { - wpa_trace_test_fail_after = 0; - } - return 0; -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - -static int wpas_ctrl_get_fail(struct wpa_supplicant *wpa_s, - char *buf, size_t buflen) -{ -#ifdef WPA_TRACE_BFD - return os_snprintf(buf, buflen, "%u:%s", wpa_trace_test_fail_after, - wpa_trace_test_fail_func); -#else /* WPA_TRACE_BFD */ - return -1; -#endif /* WPA_TRACE_BFD */ -} - - static void wpas_ctrl_event_test_cb(void *eloop_ctx, void *timeout_ctx) { struct wpa_supplicant *wpa_s = eloop_ctx; @@ -12886,15 +12820,15 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (wpas_ctrl_iface_data_test_frame(wpa_s, buf + 16) < 0) reply_len = -1; } else if (os_strncmp(buf, "TEST_ALLOC_FAIL ", 16) == 0) { - if (wpas_ctrl_test_alloc_fail(wpa_s, buf + 16) < 0) + if (testing_set_fail_pattern(true, buf + 16) < 0) reply_len = -1; } else if (os_strcmp(buf, "GET_ALLOC_FAIL") == 0) { - reply_len = wpas_ctrl_get_alloc_fail(wpa_s, reply, reply_size); + reply_len = testing_get_fail_pattern(true, reply, reply_size); } else if (os_strncmp(buf, "TEST_FAIL ", 10) == 0) { - if (wpas_ctrl_test_fail(wpa_s, buf + 10) < 0) + if (testing_set_fail_pattern(false, buf + 10) < 0) reply_len = -1; } else if (os_strcmp(buf, "GET_FAIL") == 0) { - reply_len = wpas_ctrl_get_fail(wpa_s, reply, reply_size); + reply_len = testing_get_fail_pattern(false, reply, reply_size); } else if (os_strncmp(buf, "EVENT_TEST ", 11) == 0) { if (wpas_ctrl_event_test(wpa_s, buf + 11) < 0) reply_len = -1; -- 2.38.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap