[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