diff mbox series

[v2,34/39] gdbserver: allow gdbserver to start with targets running

Message ID 20220420065013.222816-35-npiggin@gmail.com
State New
Headers show
Series gdbserver multi-threaded debugging and POWER9/10 support | expand

Commit Message

Nicholas Piggin April 20, 2022, 6:50 a.m. UTC
Rather than having to stop and start threads independently,
allow gdbserver to stop and start its targets as necessary.

Manually quiesced targets may still be debugged. This just
makes it a bit more user friendly.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 src/pdbgproxy.c | 35 ++++++++++++++++++++++++++++-------
 1 file changed, 28 insertions(+), 7 deletions(-)

Comments

Joel Stanley May 3, 2022, 7:38 a.m. UTC | #1
On Wed, 20 Apr 2022 at 06:51, Nicholas Piggin <npiggin@gmail.com> wrote:
>
> Rather than having to stop and start threads independently,
> allow gdbserver to stop and start its targets as necessary.
>
> Manually quiesced targets may still be debugged. This just
> makes it a bit more user friendly.

and they will be automatically re-enabled?

Will this be problematic unless we get the SBE restart issue fixed on p10?

>
> Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> ---
>  src/pdbgproxy.c | 35 ++++++++++++++++++++++++++++-------
>  1 file changed, 28 insertions(+), 7 deletions(-)
>
> diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
> index 1d24e68a..642cbe61 100644
> --- a/src/pdbgproxy.c
> +++ b/src/pdbgproxy.c
> @@ -51,7 +51,7 @@
>
>  #define TEST_SKIBOOT_ADDR 0x40000000
>
> -static bool all_stopped = true; /* must be started with targets stopped */
> +static bool all_stopped = false;
>  static struct pdbg_target *thread_target = NULL;
>  static struct pdbg_target *adu_target;
>  static struct timeval timeout;
> @@ -222,9 +222,13 @@ static void stop_reason(uint64_t *stack, void *priv)
>         send_stop_for_thread(thread_target);
>  }
>
> +static void start_all(void);
> +
>  static void detach(uint64_t *stack, void *priv)
>  {
>         PR_INFO("Detach debug session with client. pid %16" PRIi64 "\n", stack[0]);
> +       start_all();
> +
>         send_response(fd, OK);
>  }
>
> @@ -891,6 +895,8 @@ static void create_client(int new_fd)
>  {
>         PR_INFO("Client connected\n");
>         fd = new_fd;
> +       if (!all_stopped)
> +               stop_all();
>  }
>
>  static void destroy_client(int dead_fd)
> @@ -1095,27 +1101,38 @@ static int gdbserver(uint16_t port)
>
>         thread_target = first_target;
>
> +       for_each_path_target_class("thread", target) {
> +               if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
> +                       continue;
> +
> +               if (thread_stop(target)) {
> +                       PR_ERROR("Could not stop thread %s\n",
> +                                pdbg_target_path(target));
> +                       return -1;
> +               }
> +       }
> +
>         for_each_path_target_class("thread", target) {
>                 struct thread *thread = target_to_thread(target);
> -               struct gdb_thread *gdb_thread;
> +               struct gdb_thread *gdb_thread = thread->gdbserver_priv;
>
>                 if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
>                         continue;
>
> -               gdb_thread = thread->gdbserver_priv;
> -
>                 if (thread_getspr(target, SPR_PIR, &gdb_thread->pir)) {
>                         PR_ERROR("Error reading PIR. Are all thread in the target cores quiesced?\n");
> -                       return 0;
> +                       goto out;
>                 }
>
>                 if (gdb_thread->pir & ~0xffffULL) {
>                         /* This limit is just due to some string array sizes */
>                         PR_ERROR("PIR exceeds 16-bits.");
> -                       return 0;
> +                       goto out;
>                 }
>         }
>
> +       start_all();
> +
>         /* Select ADU target */
>         pdbg_for_each_class_target("mem", adu) {
>                 if (pdbg_target_probe(adu) == PDBG_TARGET_ENABLED)
> @@ -1124,11 +1141,15 @@ static int gdbserver(uint16_t port)
>
>         if (!adu) {
>                 fprintf(stderr, "No ADU found\n");
> -               return 0;
> +               goto out;
>         }
>
>         gdbserver_start(adu, port);
>
> +out:
> +       if (all_stopped)
> +               __start_all();
> +
>         return 0;
>  }
>  #else
> --
> 2.35.1
>
> --
> Pdbg mailing list
> Pdbg@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/pdbg
Nicholas Piggin May 10, 2022, 10:12 a.m. UTC | #2
Excerpts from Joel Stanley's message of May 3, 2022 5:38 pm:
> On Wed, 20 Apr 2022 at 06:51, Nicholas Piggin <npiggin@gmail.com> wrote:
>>
>> Rather than having to stop and start threads independently,
>> allow gdbserver to stop and start its targets as necessary.
>>
>> Manually quiesced targets may still be debugged. This just
>> makes it a bit more user friendly.
> 
> and they will be automatically re-enabled?

Yes.

> Will this be problematic unless we get the SBE restart issue fixed on p10?

It will, I've mostly been working around that by testing with
powersave=off. We could write the missing bits for the p10 xscom backend 
(which would mostly be a copy of p9 with some constant defines changed I 
think).

Thanks,
Nick
diff mbox series

Patch

diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c
index 1d24e68a..642cbe61 100644
--- a/src/pdbgproxy.c
+++ b/src/pdbgproxy.c
@@ -51,7 +51,7 @@ 
 
 #define TEST_SKIBOOT_ADDR 0x40000000
 
-static bool all_stopped = true; /* must be started with targets stopped */
+static bool all_stopped = false;
 static struct pdbg_target *thread_target = NULL;
 static struct pdbg_target *adu_target;
 static struct timeval timeout;
@@ -222,9 +222,13 @@  static void stop_reason(uint64_t *stack, void *priv)
 	send_stop_for_thread(thread_target);
 }
 
+static void start_all(void);
+
 static void detach(uint64_t *stack, void *priv)
 {
 	PR_INFO("Detach debug session with client. pid %16" PRIi64 "\n", stack[0]);
+	start_all();
+
 	send_response(fd, OK);
 }
 
@@ -891,6 +895,8 @@  static void create_client(int new_fd)
 {
 	PR_INFO("Client connected\n");
 	fd = new_fd;
+	if (!all_stopped)
+		stop_all();
 }
 
 static void destroy_client(int dead_fd)
@@ -1095,27 +1101,38 @@  static int gdbserver(uint16_t port)
 
 	thread_target = first_target;
 
+	for_each_path_target_class("thread", target) {
+		if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
+			continue;
+
+		if (thread_stop(target)) {
+			PR_ERROR("Could not stop thread %s\n",
+				 pdbg_target_path(target));
+			return -1;
+		}
+	}
+
 	for_each_path_target_class("thread", target) {
 		struct thread *thread = target_to_thread(target);
-		struct gdb_thread *gdb_thread;
+		struct gdb_thread *gdb_thread = thread->gdbserver_priv;
 
 		if (pdbg_target_status(target) != PDBG_TARGET_ENABLED)
 			continue;
 
-		gdb_thread = thread->gdbserver_priv;
-
 		if (thread_getspr(target, SPR_PIR, &gdb_thread->pir)) {
 			PR_ERROR("Error reading PIR. Are all thread in the target cores quiesced?\n");
-			return 0;
+			goto out;
 		}
 
 		if (gdb_thread->pir & ~0xffffULL) {
 			/* This limit is just due to some string array sizes */
 			PR_ERROR("PIR exceeds 16-bits.");
-			return 0;
+			goto out;
 		}
 	}
 
+	start_all();
+
 	/* Select ADU target */
 	pdbg_for_each_class_target("mem", adu) {
 		if (pdbg_target_probe(adu) == PDBG_TARGET_ENABLED)
@@ -1124,11 +1141,15 @@  static int gdbserver(uint16_t port)
 
 	if (!adu) {
 		fprintf(stderr, "No ADU found\n");
-		return 0;
+		goto out;
 	}
 
 	gdbserver_start(adu, port);
 
+out:
+	if (all_stopped)
+		__start_all();
+
 	return 0;
 }
 #else