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

Nicholas Piggin npiggin at gmail.com
Wed Apr 20 16:50:08 AEST 2022


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 at 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



More information about the Pdbg mailing list