From d36889e692788d4dc4acabd073d57f4a178e3172 Mon Sep 17 00:00:00 2001 From: Christian Eggers Date: Sat, 1 Feb 2014 10:17:17 +0100 Subject: [PATCH 1/1] RTOS: Unify wipe-out of thread list Each RTOS implementation uses it's own (similar) code to free the thread list. There are some additional issues: <---> if (pointer != NULL) free(pointer); <---> This is not necessary, free(NULL) is perfectly ok. <---> free(rtos->thread_details); rtos->thread_details = NULL; rtos->thread_count = 0; <---> The 3rd line has been missing for all RTOS but ChibiOs. There are paths in the code where rtos->thread_count is never set to NULL, which can lead to null pointer dereference of rtos->thread_details. Change-Id: I6f7045c3d4518b925cb80dd5c907a566536b34ad Signed-off-by: Christian Eggers --- Changelog: v7: - rtos_wipe_threadlist() --> rtos_free_threadlist() - removed non related changes in gdb_server.c from this patch v3: - Removed world "topic" from first line of commit message v2: - typo: "whipe" --> "wipe" Reviewed-on: http://openocd.zylin.com/1916 Tested-by: jenkins Reviewed-by: Spencer Oliver --- src/rtos/ChibiOS.c | 17 ++--------------- src/rtos/FreeRTOS.c | 20 +------------------- src/rtos/ThreadX.c | 20 +------------------- src/rtos/eCos.c | 20 +------------------- src/rtos/embKernel.c | 20 +------------------- src/rtos/rtos.c | 17 +++++++++++++++++ src/rtos/rtos.h | 1 + 7 files changed, 24 insertions(+), 91 deletions(-) diff --git a/src/rtos/ChibiOS.c b/src/rtos/ChibiOS.c index 2148e91d52..c54f43053f 100644 --- a/src/rtos/ChibiOS.c +++ b/src/rtos/ChibiOS.c @@ -296,21 +296,8 @@ static int ChibiOS_update_threads(struct rtos *rtos) } /* wipe out previous thread details if any */ - int j; - if (rtos->thread_details) { - for (j = 0; j < rtos->thread_count; j++) { - struct thread_detail *current_thread = &rtos->thread_details[j]; - if (current_thread->display_str != NULL) - free(current_thread->display_str); - if (current_thread->thread_name_str != NULL) - free(current_thread->thread_name_str); - if (current_thread->extra_info_str != NULL) - free(current_thread->extra_info_str); - } - free(rtos->thread_details); - rtos->thread_details = NULL; - rtos->thread_count = 0; - } + rtos_free_threadlist(rtos); + /* ChibiOS does not save the current thread count. We have to first * parse the double linked thread list to check for errors and the number of * threads. */ diff --git a/src/rtos/FreeRTOS.c b/src/rtos/FreeRTOS.c index 321b1e12c5..598e2d6627 100644 --- a/src/rtos/FreeRTOS.c +++ b/src/rtos/FreeRTOS.c @@ -173,25 +173,7 @@ static int FreeRTOS_update_threads(struct rtos *rtos) } /* wipe out previous thread details if any */ - if (rtos->thread_details != NULL) { - int j; - for (j = 0; j < rtos->thread_count; j++) { - if (rtos->thread_details[j].display_str != NULL) { - free(rtos->thread_details[j].display_str); - rtos->thread_details[j].display_str = NULL; - } - if (rtos->thread_details[j].thread_name_str != NULL) { - free(rtos->thread_details[j].thread_name_str); - rtos->thread_details[j].thread_name_str = NULL; - } - if (rtos->thread_details[j].extra_info_str != NULL) { - free(rtos->thread_details[j].extra_info_str); - rtos->thread_details[j].extra_info_str = NULL; - } - } - free(rtos->thread_details); - rtos->thread_details = NULL; - } + rtos_free_threadlist(rtos); /* read the current thread */ retval = target_read_buffer(rtos->target, diff --git a/src/rtos/ThreadX.c b/src/rtos/ThreadX.c index 19dc463602..add34b4f4d 100644 --- a/src/rtos/ThreadX.c +++ b/src/rtos/ThreadX.c @@ -155,25 +155,7 @@ static int ThreadX_update_threads(struct rtos *rtos) } /* wipe out previous thread details if any */ - if (rtos->thread_details != NULL) { - int j; - for (j = 0; j < rtos->thread_count; j++) { - if (rtos->thread_details[j].display_str != NULL) { - free(rtos->thread_details[j].display_str); - rtos->thread_details[j].display_str = NULL; - } - if (rtos->thread_details[j].thread_name_str != NULL) { - free(rtos->thread_details[j].thread_name_str); - rtos->thread_details[j].thread_name_str = NULL; - } - if (rtos->thread_details[j].extra_info_str != NULL) { - free(rtos->thread_details[j].extra_info_str); - rtos->thread_details[j].extra_info_str = NULL; - } - } - free(rtos->thread_details); - rtos->thread_details = NULL; - } + rtos_free_threadlist(rtos); /* read the current thread id */ retval = target_read_buffer(rtos->target, diff --git a/src/rtos/eCos.c b/src/rtos/eCos.c index 9ab88dec01..7310d6d640 100644 --- a/src/rtos/eCos.c +++ b/src/rtos/eCos.c @@ -125,25 +125,7 @@ static int eCos_update_threads(struct rtos *rtos) } /* wipe out previous thread details if any */ - if (rtos->thread_details != NULL) { - int j; - for (j = 0; j < rtos->thread_count; j++) { - if (rtos->thread_details[j].display_str != NULL) { - free(rtos->thread_details[j].display_str); - rtos->thread_details[j].display_str = NULL; - } - if (rtos->thread_details[j].thread_name_str != NULL) { - free(rtos->thread_details[j].thread_name_str); - rtos->thread_details[j].thread_name_str = NULL; - } - if (rtos->thread_details[j].extra_info_str != NULL) { - free(rtos->thread_details[j].extra_info_str); - rtos->thread_details[j].extra_info_str = NULL; - } - } - free(rtos->thread_details); - rtos->thread_details = NULL; - } + rtos_free_threadlist(rtos); /* determine the number of current threads */ uint32_t thread_list_head = rtos->symbols[eCos_VAL_thread_list].address; diff --git a/src/rtos/embKernel.c b/src/rtos/embKernel.c index f605deb3c5..76c0bd23b2 100644 --- a/src/rtos/embKernel.c +++ b/src/rtos/embKernel.c @@ -206,25 +206,7 @@ static int embKernel_update_threads(struct rtos *rtos) } /* wipe out previous thread details if any */ - if (rtos->thread_details != NULL) { - int j; - for (j = 0; j < rtos->thread_count; j++) { - if (rtos->thread_details[j].display_str != NULL) { - free(rtos->thread_details[j].display_str); - rtos->thread_details[j].display_str = NULL; - } - if (rtos->thread_details[j].thread_name_str != NULL) { - free(rtos->thread_details[j].thread_name_str); - rtos->thread_details[j].thread_name_str = NULL; - } - if (rtos->thread_details[j].extra_info_str != NULL) { - free(rtos->thread_details[j].extra_info_str); - rtos->thread_details[j].extra_info_str = NULL; - } - } - free(rtos->thread_details); - rtos->thread_details = NULL; - } + rtos_free_threadlist(rtos); param = (const struct embKernel_params *) rtos->rtos_specific_params; diff --git a/src/rtos/rtos.c b/src/rtos/rtos.c index cdd37608ed..0082ced1ff 100644 --- a/src/rtos/rtos.c +++ b/src/rtos/rtos.c @@ -513,3 +513,20 @@ int rtos_update_threads(struct target *target) target->rtos->type->update_threads(target->rtos); return ERROR_OK; } + +void rtos_free_threadlist(struct rtos *rtos) +{ + if (rtos->thread_details) { + int j; + + for (j = 0; j < rtos->thread_count; j++) { + struct thread_detail *current_thread = &rtos->thread_details[j]; + free(current_thread->display_str); + free(current_thread->thread_name_str); + free(current_thread->extra_info_str); + } + free(rtos->thread_details); + rtos->thread_details = NULL; + rtos->thread_count = 0; + } +} diff --git a/src/rtos/rtos.h b/src/rtos/rtos.h index 12a96d2ab0..f8aa33f10b 100644 --- a/src/rtos/rtos.h +++ b/src/rtos/rtos.h @@ -98,6 +98,7 @@ int rtos_try_next(struct target *target); int gdb_thread_packet(struct connection *connection, char *packet, int packet_size); int rtos_get_gdb_reg_list(struct connection *connection); int rtos_update_threads(struct target *target); +void rtos_free_threadlist(struct rtos *rtos); int rtos_smp_init(struct target *target); /* function for handling symbol access */ int rtos_qsymbol(struct connection *connection, char *packet, int packet_size); -- 2.30.2