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>__archive__
parent
9b2577742c
commit
da0d1e374b
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue