semihosting: fix memory leak and double free
Resolve two problems that occurred when working with semihosting service
through multiple connection cycles (connect-disconnect-reconnect):
1) Double free:
When the same service handles multiple connections sequentially,
the same memory gets freed repeatedly, because function
'semihosting_service_connection_closed_handler()' incorrectly frees
service->priv->name on every connection closure.
2) Memory leak:
Function 'free_services()' misses service->priv->name cleanup for
semihosting redirection. Memory remains allocated after service
destruction.
The solution introduces a new 'dtor()' field in the service structure
that is called exactly once during free_service() execution.
To reproduce the issue, you can do the following:
1. openocd -f target.cfg -c init -c 'arm semihosting enable' -c
'arm semihosting_redirect tcp 4445'
# in another terminal
2. nc localhost 4445
3. Ctr+C
4. nc localhost 4445
5. Ctr+C
Change-Id: I0dc8021cc3e21c5af619c71a1821a1afe9bffe78
Signed-off-by: Kulyatskaya Alexandra <a.kulyatskaya@syntacore.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/9196
Tested-by: jenkins
Reviewed-by: Evgeniy Naydanov <eugnay@gmail.com>
Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com>
This commit is contained in:
committed by
Antonio Borneo
parent
55e9160509
commit
5ff384be08
@@ -1800,13 +1800,12 @@ static int semihosting_service_input_handler(struct connection *connection)
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int semihosting_service_connection_closed_handler(struct connection *connection)
|
||||
static void semihosting_service_dtor_handler(struct service *service)
|
||||
{
|
||||
struct semihosting_tcp_service *service = connection->service->priv;
|
||||
if (service)
|
||||
free(service->name);
|
||||
struct semihosting_tcp_service *service_priv = service->priv;
|
||||
if (service_priv)
|
||||
free(service_priv->name);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static void semihosting_tcp_close_cnx(struct semihosting *semihosting)
|
||||
@@ -1825,7 +1824,8 @@ static const struct service_driver semihosting_service_driver = {
|
||||
.new_connection_during_keep_alive_handler = NULL,
|
||||
.new_connection_handler = semihosting_service_new_connection_handler,
|
||||
.input_handler = semihosting_service_input_handler,
|
||||
.connection_closed_handler = semihosting_service_connection_closed_handler,
|
||||
.service_dtor_handler = semihosting_service_dtor_handler,
|
||||
.connection_closed_handler = NULL,
|
||||
.keep_client_alive_handler = NULL,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user