This is an automated email from Gerrit.

"Antonio Borneo <[email protected]>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/9063

-- gerrit

commit 0e4381206ef786705d12eddcf8475523396aaba6
Author: Antonio Borneo <[email protected]>
Date:   Tue Jul 29 16:14:38 2025 +0200

    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 <[email protected]>

diff --git a/src/target/target.c b/src/target/target.c
index 995adbc9d3..8fdaeee26d 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -4667,11 +4667,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),
@@ -4687,7 +4694,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;
 

-- 

Reply via email to