This is an automated email from Gerrit.

"Anatoly P <anatoly.parshint...@syntacore.com>" just uploaded a new patch set 
to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8471

-- gerrit

commit a1a1957e5d5cdc61d013451f064e767642953e2a
Author: Parshintsev Anatoly <anatoly.parshint...@syntacore.com>
Date:   Fri Aug 30 22:45:07 2024 +0300

    rtos/hwthread: fix threadid generation
    
    Looks like 7f2d3e2925 introduced a regression by incorrectly assigning
    threads. The title of the commit message says that the intention was to
    "derive threadid from SMP index", this is not what happens, however.
    Instead threadid is assigned based on an index of all examined targets
    in an SMP group.
    
    This introduces two logical errors.
    
    *Error 1*
    
    Here is the code that assigns threads to harts:
    
    ```
    foreach_smp_target(head, target->smp_targets) {
      struct target *curr = head->target;
    
      if (!target_was_examined(curr))
        continue;
    
      threadid_t tid = threads_found + 1;
      hwthread_fill_thread(rtos, curr, threads_found, tid);
    ```
    
    Now, imagine a situation when we have two targets: `target.A` and 
`target.B`.
    Let's assume that `target.A` is NOT examined (it could be under reset, for 
example).
    Then, according to the algorithm when assigning thread identifiers 
`target.B`
    will be assigned tid of 1. The respected inferior on GDB side will be called
    `Thread 1`.
    
    Now, imagine that `target.A` activates and succefully examined - OpenOCD 
will
    re-assign thread identifiers. And now on GDB side `Thread 1` will represent
    the state of `target.A`. Which is incorrect.
    
    *Error 2*
    
    The reverse mapping between `threadid` and targets does not take the state
    of targets into account.
    
    ```
    static struct target *hwthread_find_thread(struct target *target, 
threadid_t thread_id)
    ...
      threadid_t tid = 1;
      foreach_smp_target(head, target->smp_targets) {
        if (thread_id == tid)
          head->target;
        ++tid;
      }
    ```
    
    So the constructed mapping is incorrect. Since in example above `Thread 1` 
will
    get mapped to `target.A`.
    
    *Solution:*
    
    It seems that threadids should be assigned based on position of the thread
    in an smp group disregarding the target state.
    
    Change-Id: Ib93b7ed3bb03696afdf56a105b333e22b9ec69b5
    Signed-off-by: Parshintsev Anatoly <anatoly.parshint...@syntacore.com>

diff --git a/src/rtos/hwthread.c b/src/rtos/hwthread.c
index 748e71c3dc..4fe8419025 100644
--- a/src/rtos/hwthread.c
+++ b/src/rtos/hwthread.c
@@ -133,7 +133,7 @@ static int hwthread_update_threads(struct rtos *rtos)
                        if (!target_was_examined(curr))
                                continue;
 
-                       threadid_t tid = threads_found + 1;
+                       threadid_t tid = threadid_from_target(curr);
                        hwthread_fill_thread(rtos, curr, threads_found, tid);
 
                        /* find an interesting thread to set as current */

-- 

Reply via email to