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>
This commit is contained in:
Christian Eggers 2014-02-02 13:25:16 +01:00 committed by Spencer Oliver
parent 9b2577742c
commit da0d1e374b

View File

@ -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) static int gdb_generate_target_description(struct target *target, char **tdesc_out)
{ {
int retval = ERROR_OK; int retval = ERROR_OK;
struct reg **reg_list; struct reg **reg_list = NULL;
int reg_list_size; int reg_list_size;
char **features = NULL;
int feature_list_size = 0;
char *tdesc = NULL; char *tdesc = NULL;
int pos = 0; int pos = 0;
int size = 0; int size = 0;
@ -2061,21 +2063,22 @@ static int gdb_generate_target_description(struct target *target, char **tdesc_o
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("get register list failed"); LOG_ERROR("get register list failed");
return ERROR_FAIL; retval = ERROR_FAIL;
goto error;
} }
if (reg_list_size <= 0) { if (reg_list_size <= 0) {
free(reg_list); LOG_ERROR("get register list failed");
return ERROR_FAIL; retval = ERROR_FAIL;
goto error;
} }
char **features = NULL;
/* Get a list of available target registers features */ /* 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) { if (retval != ERROR_OK) {
LOG_ERROR("Can't get the registers feature list"); LOG_ERROR("Can't get the registers feature list");
free(reg_list); retval = ERROR_FAIL;
return ERROR_FAIL; goto error;
} }
/* If we found some features associated with registers, create sections */ /* 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, xml_printf(&retval, &tdesc, &pos, &size,
"</target>\n"); "</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(features);
free(reg_list);
if (retval == ERROR_OK) if (retval == ERROR_OK)
*tdesc_out = tdesc; *tdesc_out = tdesc;
@ -2225,6 +2233,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte
int retval = ERROR_OK; int retval = ERROR_OK;
struct reg **reg_list = NULL; struct reg **reg_list = NULL;
int reg_list_size = 0; int reg_list_size = 0;
char **features = NULL;
int feature_list_size = 0; int feature_list_size = 0;
char **features = NULL; char **features = NULL;
@ -2236,6 +2245,7 @@ static int gdb_target_description_supported(struct target *target, int *supporte
} }
if (reg_list_size <= 0) { if (reg_list_size <= 0) {
LOG_ERROR("get register list failed");
retval = ERROR_FAIL; retval = ERROR_FAIL;
goto error; goto error;
} }
@ -2255,11 +2265,13 @@ static int gdb_target_description_supported(struct target *target, int *supporte
} }
error: error:
if (reg_list != NULL)
free(reg_list);
if (features != NULL) /* note: features[] contains (feature_list_size + 1) elements */
free(features); for (int j = feature_list_size; j >= 0; j--)
free(features[j]);
free(features);
free(reg_list);
return retval; return retval;
} }