mirror of
https://github.com/openocd-org/openocd.git
synced 2025-10-14 02:58:23 +08:00
target: allow events to be modified inside an event handler
The code in an event handler can use the command '$target_name configure' to add a new event or to remove or modify an existing event. Such operation impacts the list of event of the target and also modify the event itself, causing OpenOCD to access memory already deallocated or not anymore valid. Use the safe version of list_for_each_entry() to iterate on the list of events. Make a local copy of the current event, to avoid issues if it gets deallocated. Use Jim_IncrRefCount() to guarantee that the body of the event handler don't gets deallocated when the event is removed. Change-Id: I936e35adddc030ba7cec6e2fc0c7d3b1b5c4a863 Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com> Reviewed-on: https://review.openocd.org/c/openocd/+/9063 Reviewed-by: Evgeniy Naydanov <evgeniy.naydanov@syntacore.com> Tested-by: jenkins
This commit is contained in:
@@ -4663,11 +4663,18 @@ COMMAND_HANDLER(handle_target_write_memory)
|
||||
*/
|
||||
void target_handle_event(struct target *target, enum target_event e)
|
||||
{
|
||||
struct target_event_action *teap;
|
||||
struct target_event_action *teap, *tmp;
|
||||
int retval;
|
||||
|
||||
list_for_each_entry(teap, &target->events_action, list) {
|
||||
list_for_each_entry_safe(teap, tmp, &target->events_action, list) {
|
||||
if (teap->event == e) {
|
||||
/*
|
||||
* The event can be destroyed by its own handler.
|
||||
* Make a local copy and use it in place of the original.
|
||||
*/
|
||||
struct target_event_action local_teap = *teap;
|
||||
teap = &local_teap;
|
||||
|
||||
LOG_DEBUG("target: %s (%s) event: %d (%s) action: %s",
|
||||
target_name(target),
|
||||
target_type_name(target),
|
||||
@@ -4683,7 +4690,13 @@ void target_handle_event(struct target *target, enum target_event e)
|
||||
struct target *saved_target_override = cmd_ctx->current_target_override;
|
||||
cmd_ctx->current_target_override = target;
|
||||
|
||||
/*
|
||||
* The event can be destroyed by its own handler.
|
||||
* Prevent the body to get deallocated by Jim.
|
||||
*/
|
||||
Jim_IncrRefCount(teap->body);
|
||||
retval = Jim_EvalObj(teap->interp, teap->body);
|
||||
Jim_DecrRefCount(teap->interp, teap->body);
|
||||
|
||||
cmd_ctx->current_target_override = saved_target_override;
|
||||
|
||||
|
Reference in New Issue
Block a user