[Pdbg] [PATCH v2 31/39] gdbserver: multi-thread polling and stop-reason

Joel Stanley joel at jms.id.au
Tue May 3 17:33:59 AEST 2022


On Wed, 20 Apr 2022 at 06:51, Nicholas Piggin <npiggin at gmail.com> wrote:
>
> Rework poll() and the stop reason code to support multi-threaded
> debugging.
>
> - Make poll() iterate over all target threads to check whether any
>   are stopped.
>
> - If any are found stopped, stop the rest. Poll SPATTN for all
>   target threads.
>
> This provides the basis for "all-stop" threaded debugging mode,
> which is what seems to work best for bare metal debugging.
>
> Signed-off-by: Nicholas Piggin <npiggin at gmail.com>

Reviewed-by: Joel Stanley <joel at jms.id.au>

> ---
>  src/pdbgproxy.c | 75 +++++++++++++++++++++++++++++--------------------
>  1 file changed, 44 insertions(+), 31 deletions(-)
>
> diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
> index c5870091..735615c6 100644
> --- a/src/pdbgproxy.c
> +++ b/src/pdbgproxy.c
> @@ -683,60 +683,73 @@ static void stop_all(void)
>                         PR_ERROR("Could not quiesce thread\n");
>                         /* How to fix? */
>                 }
> +
> +               if (thread_check_attn(target)) {
> +                       struct thread *thread = target_to_thread(target);
> +                       struct gdb_thread *gdb_thread = thread->gdbserver_priv;
> +                       uint64_t nia;
> +
> +                       PR_INFO("thread pir=%"PRIx64" hit attn\n", gdb_thread->pir);
> +
> +                       if (!(status.active))
> +                               PR_ERROR("Error thread inactive after trap\n");
> +                       /* Restore NIA to before break */
> +                       if (thread_getnia(target, &nia))
> +                               PR_ERROR("Error during getnia\n");
> +                       if (thread_putnia(target, nia - 4))
> +                               PR_ERROR("Error during putnia\n");
> +               }
>         }
>  }
>
>  static void interrupt(uint64_t *stack, void *priv)
>  {
> -       struct thread_state status;
> -
>         PR_INFO("Interrupt from gdb client\n");
> +       if (state != IDLE) {
> +               stop_all();
>
> -       stop_all();
> -
> -       status = thread_status(thread_target);
> -       if (!(status.quiesced)) {
> -               PR_ERROR("Could not quiesce thread\n");
> -               return;
> +               state = IDLE;
> +               poll_interval = VCONT_POLL_DELAY;
>         }
> -       state = IDLE;
> -       poll_interval = VCONT_POLL_DELAY;
> +
>         send_response(fd, TRAP);
>  }
>
> -static void poll(void)
> +static bool poll_threads(void)
>  {
> -       struct thread_state status;
> +       struct pdbg_target *target;
> +
> +       for_each_path_target_class("thread", target) {
> +               struct thread_state status;
> +
> +               if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
> +                       continue;
>
> +               target->probe(target);
> +               status = thread_status(target);
> +               if (status.quiesced)
> +                       return true;
> +       }
> +       return false;
> +}
> +
> +static void poll(void)
> +{
>         if (state != SIGNAL_WAIT)
>                 return;
>
> -       thread_target->probe(thread_target);
> -       status = thread_status(thread_target);
> -
> -       if (!(status.quiesced))
> +       if (!poll_threads())
>                 return;
>
> +       /* Something hit a breakpoint */
> +
> +       stop_all();
> +
>         set_attn(false);
>
>         state = IDLE;
>         poll_interval = VCONT_POLL_DELAY;
>
> -       if (thread_check_attn(thread_target)) {
> -               uint64_t nia;
> -
> -               if (!(status.active)) {
> -                       PR_ERROR("Thread inactive after trap\n");
> -                       send_response(fd, ERROR(EPERM));
> -                       return;
> -               }
> -
> -               /* Restore NIA */
> -               if (thread_getnia(thread_target, &nia))
> -                       PR_ERROR("Error during getnia\n");
> -               if (thread_putnia(thread_target, nia - 4))
> -                       PR_ERROR("Error during putnia\n");
> -       }
>         send_response(fd, TRAP);
>  }
>
> --
> 2.35.1
>
> --
> Pdbg mailing list
> Pdbg at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/pdbg


More information about the Pdbg mailing list