Make monitor targets always have a thread

Pedro Alves
2008-07-03T15:23:54Z

[-- Attachment #1: Type: text/plain, Size: 620 bytes --]

This patch makes the monitor targets always register an execution control
task in GDB's thread list. Needed to clean up inferior control, and
get rid of context switching.

I confirmed that it builds with x86_64-unknown-linux-gnu x h8300-elf cross,
and that it doesn't introduce any new warnings (this file is built without
-Werror).

As I said in my previous email, I don't even know how to test this, although
I don't except to be any fallout.

Does it look OK? Can anyone instruct me how to test this; or do a test
spin for me; or claim that it looks ok, and we'll fix problems as
they arise? :-)

--
Pedro Alves

[-- Attachment #2: monitor_always_a_thread.diff --]
[-- Type: text/x-diff, Size: 5477 bytes --]

2008-07-03 Pedro Alves <pedro@codesourcery.com>

* monitor (monitor_ptid): New global.
(monitor_open): Silently add the main task to GDB's thread list.
(monitor_close, monitor_mourn_inferior): Silently delete the main
task from GDB's thread list.
(monitor_thread_alive, monitor_pid_to_str): New.
(init_base_monitor_ops): Register monitor_thread_alive and
monitor_pid_to_str.
(_initialize_remote_monitors): Initialize monitor_ptid.

* gdbthread.h (delete_thread_silent): Declare.
* thread.c (delete_thread): Rename to ...
(delete_thread_1): ... this. Add "silent" parameter. If silent,
don't do exit notifications.
(delete_thread, delete_thread_silent): New, as wrappers to
delete_thread_1.

---
gdb/gdbthread.h | 5 +++++
gdb/monitor.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
gdb/thread.c | 21 ++++++++++++++++++---
3 files changed, 71 insertions(+), 4 deletions(-)

Index: src/gdb/monitor.c
===================================================================
--- src.orig/gdb/monitor.c 2008-07-03 16:15:04.000000000 +0100
+++ src/gdb/monitor.c 2008-07-03 16:21:04.000000000 +0100
@@ -106,6 +106,13 @@ static int dump_reg_flag; /* Non-zero me
static int first_time = 0; /* is this the first time we're executing after
gaving created the child proccess? */

+
+/* This is the ptid we use while we're connected to a monitor. It's
+ value is arbitrary, as monitor targets don't have a notion or
+ processes or thread, but we need something non-null to place in
+ inferior_ptid. */
+static ptid_t monitor_ptid;
+
#define TARGET_BUF_SIZE 2048

/* Monitor specific debugging information. Typically only useful to
@@ -808,7 +815,9 @@ monitor_open (char *args, struct monitor
/* Start afresh. */
init_thread_list ();

- inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */
+ /* Make run command think we are busy... */
+ inferior_ptid = monitor_ptid;
+ add_thread_silent (inferior_ptid);

/* Give monitor_wait something to read */

@@ -834,6 +843,8 @@ monitor_close (int quitting)
}

monitor_desc = NULL;
+
+ delete_thread_silent (monitor_ptid);
}

/* Terminate the open connection to the remote debugger. Use this
@@ -2002,6 +2013,7 @@ static void
monitor_mourn_inferior (void)
{
unpush_target (targ_ops);
+ delete_thread_silent (monitor_ptid);
generic_mourn_inferior (); /* Do all the proper things now */
}

@@ -2215,6 +2227,35 @@ monitor_get_dev_name (void)
return dev_name;
}

+/* Check to see if a thread is still alive. */
+
+static int
+monitor_thread_alive (ptid_t ptid)
+{
+ if (ptid_equal (ptid, monitor_ptid))
+ /* The monitor's task is always alive. */
+ return 1;
+
+ return 0;
+}
+
+/* Convert a thread ID to a string. Returns the string in a static
+ buffer. */
+
+static char *
+monitor_pid_to_str (ptid_t ptid)
+{
+ static char buf[64];
+
+ if (ptid_equal (monitor_ptid, ptid))
+ {
+ xsnprintf (buf, sizeof buf, "Thread ");
+ return buf;
+ }
+
+ return normal_pid_to_str (ptid);
+}
+
static struct target_ops monitor_ops;

static void
@@ -2238,6 +2279,8 @@ init_base_monitor_ops (void)
monitor_ops.to_stop = monitor_stop;
monitor_ops.to_rcmd = monitor_rcmd;
monitor_ops.to_log_command = serial_log_command;
+ monitor_ops.to_thread_alive = monitor_thread_alive;
+ monitor_ops.to_pid_to_str = monitor_pid_to_str;
monitor_ops.to_stratum = process_stratum;
monitor_ops.to_has_all_memory = 1;
monitor_ops.to_has_memory = 1;
@@ -2282,4 +2325,8 @@ is displayed."),
NULL,
NULL, /* FIXME: i18n: */
&setdebuglist, &showdebuglist);
+
+ /* Yes, 42000 is arbitrary. The only sense out of it, is that it
+ isn't 0. */
+ monitor_ptid = ptid_build (42000, 0, 42000);
}
Index: src/gdb/gdbthread.h
===================================================================
--- src.orig/gdb/gdbthread.h 2008-07-03 16:15:04.000000000 +0100
+++ src/gdb/gdbthread.h 2008-07-03 16:15:06.000000000 +0100
@@ -91,6 +91,11 @@ extern struct thread_info *add_thread_wi
/* Delete an existing thread list entry. */
extern void delete_thread (ptid_t);

+/* Delete an existing thread list entry, and be quiet about it. Used
+ after the process this thread having belonged to having already
+ exited, for example. */
+extern void delete_thread_silent (ptid_t);
+
/* Delete a step_resume_breakpoint from the thread database. */
extern void delete_step_resume_breakpoint (void *);

Index: src/gdb/thread.c
===================================================================
--- src.orig/gdb/thread.c 2008-07-03 16:15:04.000000000 +0100
+++ src/gdb/thread.c 2008-07-03 16:15:06.000000000 +0100
@@ -153,8 +153,10 @@ add_thread (ptid_t ptid)
return add_thread_with_info (ptid, NULL);
}

-void
-delete_thread (ptid_t ptid)
+/* Delete thread PTID. If SILENT, don't notify the observer of this
+ exit. */
+static void
+delete_thread_1 (ptid_t ptid, int silent)
{
struct thread_info *tp, *tpprev;

@@ -172,11 +174,24 @@ delete_thread (ptid_t ptid)
else
thread_list = tp->next;

- observer_notify_thread_exit (tp);
+ if (!silent)
+ observer_notify_thread_exit (tp);

free_thread (tp);
}

+void
+delete_thread (ptid_t ptid)
+{
+ delete_thread_1 (ptid, 0 /* not silent */);
+}
+
+void
+delete_thread_silent (ptid_t ptid)
+{
+ delete_thread_1 (ptid, 1 /* silent */);
+}
+
static struct thread_info *
find_thread_id (int num)
{