diff options
author | Christian Eggers <ceggers@gmx.de> | 2014-02-02 13:25:16 +0100 |
---|---|---|
committer | Spencer Oliver <spen@spen-soft.co.uk> | 2014-03-04 20:17:53 +0000 |
commit | da0d1e374bdf7eabf27c0e31dec57532e4d7e4c8 (patch) | |
tree | dec34d20b68a7c92b5731d4fb77229ed619c6607 /src/server/gdb_server.c | |
parent | 9b2577742cc49683ab0ea8506d93e3e285b53bbd (diff) |
gdb_server: fix memory leaks in users of get_reg_features_list()
v4:
- changed first line of commit message
v3:
- added extra LOG_ERROR() message
v2:
- Added missing "goto error"
- free also the on extra element of features[]
In contrast to target_get_gdb_reg_list(), the list returned by
get_reg_features_list() consists of items which are itself
malloc'ed.
--> Free the list items prior freeing the list itself.
Additionally:
- gdb_generate_target_description():
o Do error handling similar as gdb_get_target_description_chunk() does.
- gdb_get_target_description_chunk()
o **features must be initialised prior an "goto error" can happen
Change-Id: Iad07824618c51084e0aa0499ee6fc96198b320f0
Signed-off-by: Christian Eggers <ceggers@gmx.de>
Reviewed-on: http://openocd.zylin.com/1917
Tested-by: jenkins
Reviewed-by: Trevor Woerner <trevor.woerner@linaro.org>
Reviewed-by: Spencer Oliver <spen@spen-soft.co.uk>
Diffstat (limited to 'src/server/gdb_server.c')
-rw-r--r-- | src/server/gdb_server.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index d4cc2744..63c5f6bb 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -2050,8 +2050,10 @@ static int get_reg_features_list(struct target *target, char **feature_list[], i static int gdb_generate_target_description(struct target *target, char **tdesc_out) { int retval = ERROR_OK; - struct reg **reg_list; + struct reg **reg_list = NULL; int reg_list_size; + char **features = NULL; + int feature_list_size = 0; char *tdesc = NULL; int pos = 0; int size = 0; @@ -2061,21 +2063,22 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o if (retval != ERROR_OK) { LOG_ERROR("get register list failed"); - return ERROR_FAIL; + retval = ERROR_FAIL; + goto error; } if (reg_list_size <= 0) { - free(reg_list); - return ERROR_FAIL; + LOG_ERROR("get register list failed"); + retval = ERROR_FAIL; + goto error; } - char **features = NULL; /* Get a list of available target registers features */ - retval = get_reg_features_list(target, &features, NULL, reg_list, reg_list_size); + retval = get_reg_features_list(target, &features, &feature_list_size, reg_list, reg_list_size); if (retval != ERROR_OK) { LOG_ERROR("Can't get the registers feature list"); - free(reg_list); - return ERROR_FAIL; + retval = ERROR_FAIL; + goto error; } /* If we found some features associated with registers, create sections */ @@ -2155,8 +2158,13 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o xml_printf(&retval, &tdesc, &pos, &size, "</target>\n"); - free(reg_list); +error: + + /* note: features[] contains (feature_list_size + 1) elements */ + for (int j = feature_list_size; j >= 0; j--) + free(features[j]); free(features); + free(reg_list); if (retval == ERROR_OK) *tdesc_out = tdesc; @@ -2225,6 +2233,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte int retval = ERROR_OK; struct reg **reg_list = NULL; int reg_list_size = 0; + char **features = NULL; int feature_list_size = 0; char **features = NULL; @@ -2236,6 +2245,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte } if (reg_list_size <= 0) { + LOG_ERROR("get register list failed"); retval = ERROR_FAIL; goto error; } @@ -2255,11 +2265,13 @@ static int gdb_target_description_supported(struct target *target, int *supporte } error: - if (reg_list != NULL) - free(reg_list); - if (features != NULL) - free(features); + /* note: features[] contains (feature_list_size + 1) elements */ + for (int j = feature_list_size; j >= 0; j--) + free(features[j]); + free(features); + + free(reg_list); return retval; } |