This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH RFC] Make lin-lwp.c functions use target vectors, 3rd try
- To: gdb-patches at sources dot redhat dot com,kettenis at science dot uva dot nl
- Subject: [PATCH RFC] Make lin-lwp.c functions use target vectors, 3rd try
- From: John S. Kallal <jskallal at home dot com>
- Date: Tue, 22 May 2001 23:45:13 -0400
- Cc: Michael Snyder <msnyder at cygnus dot com>
- Reply-To: jskallal at home dot com
Hi Mark,
Here is my revised patch.
Sorry about the blank mail message. I send it in error.
I need to get some sleep.
This patch comes from my work trying to get Linux threaded
debugging working through GDBSERVER. As a start the following
patch somewhat makes the routines in lin-lwp.c work through
the target stack. However even with this patch, the lin-lwp.c
code still does many system calls and otherwise bypasses the
target vectors.
How am I not following the coding standards?
Am I coding this change correctly?
Is this change, the correct thing to do?
Whould it be better to place the lin-lwp target
into the target stack at some new stratum? Read
http://sources.redhat.com/ml/gdb/2001-05/msg00302.html.
Is it even practical to do threaded debugging
Linux to Linux via GDBSERVER, without doing major
changes to the GDB remote serial protocal and/or
GDBSERVER? I think it can be done but some of
the remote serial command may not be as abstract
as we would desire.
2001-05-22 John S. Kallal <jskallal@home.com>
* lin-lwp.c (get_target_below) : New function to get the current
target at the process_stratum.
* lin-lwp.c (find_target_stratum) : New function. This function
acts as a helper function to get_target_below.
* lin-lwp.c (lin_lwp_attach) : Change code to call target
function via target vector. (lin_lwp_attach) : Ditto.
(lin_lwp_detach) : Ditto. (resume_callback) : Ditto.
(lin_lwp_resume) : Ditto. (lin_lwp_wait) : Ditto at three places.
(lin_lwp_kill) : Ditto. (lin_lwp_create_inferior) : Ditto.
(lin_lwp_mourn_inferio) : Ditto. (lin_lwp_fetch_registers) :
Ditto. (lin_lwp_store_registers) : Ditto
(lin_lwp_xfer_memory) : Ditto.
* lin-lwp.c : Disable reference to external struct child_ops.
--- ../gdb+dejagnu-20010518-org/gdb/lin-lwp.c Tue May 22 17:23:22 2001
+++ gdb/lin-lwp.c Tue May 22 13:48:47 2001
@@ -118,7 +118,9 @@ ptid_t trap_ptid;
static struct target_ops lin_lwp_ops;
/* The standard child operations. */
+#if 0
extern struct target_ops child_ops;
+#endif
/* Since we cannot wait (in lin_lwp_wait) for the initial process and
any cloned processes with a single call to waitpid, we have to use
@@ -144,6 +146,7 @@ static sigset_t blocked_mask;
/* Prototypes for local functions. */
static int stop_wait_callback (struct lwp_info *lp, void *data);
+static struct target_ops *get_target_below (void);
/* Initialize the list of LWPs. Note that this module, contrary to
@@ -334,10 +337,14 @@ static void
lin_lwp_attach (char *args, int from_tty)
{
struct lwp_info *lp;
+ struct target_ops *process_ops;
+ process_ops = get_target_below ();
/* FIXME: We should probably accept a list of process id's, and
attach all of them. */
- child_ops.to_attach (args, from_tty);
+ if (process_ops!=NULL)
+ if ((process_ops->to_attach)!=NULL)
+ process_ops->to_attach (args, from_tty);
/* Add the initial process as the first LWP to the list. */
lp = add_lwp (BUILD_LWP (PIDGET (inferior_ptid), PIDGET (inferior_ptid)));
@@ -392,6 +399,8 @@ detach_callback (struct lwp_info *lp, vo
static void
lin_lwp_detach (char *args, int from_tty)
{
+ struct target_ops *process_ops;
+
iterate_over_lwps (detach_callback, NULL);
/* Only the initial (uncloned) process should be left right now. */
@@ -407,7 +416,11 @@ lin_lwp_detach (char *args, int from_tty
sigemptyset (&blocked_mask);
inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
- child_ops.to_detach (args, from_tty);
+
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_detach)!=NULL)
+ (process_ops->to_detach) (args, from_tty);
}
@@ -435,6 +448,8 @@ find_lwp_callback (struct thread_info *t
static int
resume_callback (struct lwp_info *lp, void *data)
{
+ struct target_ops *process_ops;
+
if (lp->stopped && lp->status == 0)
{
struct thread_info *tp;
@@ -460,7 +475,12 @@ resume_callback (struct lwp_info *lp, vo
}
#endif
- child_resume (pid_to_ptid (GET_LWP (lp->ptid)), 0, TARGET_SIGNAL_0);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_resume)!=NULL)
+ (process_ops->to_resume) (pid_to_ptid (GET_LWP (lp->ptid)),
+ 0, TARGET_SIGNAL_0);
+
lp->stopped = 0;
lp->step = 0;
}
@@ -471,6 +491,7 @@ resume_callback (struct lwp_info *lp, vo
static void
lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo)
{
+ struct target_ops *process_ops;
struct lwp_info *lp;
int resume_all;
@@ -511,7 +532,10 @@ lin_lwp_resume (ptid_t ptid, int step, e
if (resume_all)
iterate_over_lwps (resume_callback, NULL);
- child_resume (ptid, step, signo);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_resume)!=NULL)
+ (process_ops->to_resume) (ptid, step, signo);
}
@@ -653,6 +677,7 @@ running_callback (struct lwp_info *lp, v
static ptid_t
lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
+ struct target_ops *process_ops;
struct lwp_info *lp = NULL;
int options = 0;
int status = 0;
@@ -727,8 +752,12 @@ lin_lwp_wait (ptid_t ptid, struct target
/* Resume the thread. It should halt immediately returning the
pending SIGSTOP. */
- child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
- TARGET_SIGNAL_0);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_resume)!=NULL)
+ (process_ops->to_resume) (pid_to_ptid (GET_LWP (lp->ptid)),
+ lp->step,TARGET_SIGNAL_0);
+
lp->stopped = 0;
/* This should catch the pending SIGSTOP. */
@@ -813,8 +842,12 @@ lin_lwp_wait (ptid_t ptid, struct target
/* This is a delayed SIGSTOP. */
lp->signalled = 0;
- child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
- TARGET_SIGNAL_0);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_resume)!=NULL)
+ (process_ops->to_resume) (pid_to_ptid (GET_LWP (lp->ptid)),
+ lp->step, TARGET_SIGNAL_0);
+
lp->stopped = 0;
/* Discard the event. */
@@ -859,7 +892,13 @@ lin_lwp_wait (ptid_t ptid, struct target
&& signal_print_state (signo) == 0
&& signal_pass_state (signo) == 1)
{
- child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo);
+
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_resume)!=NULL)
+ (process_ops->to_resume) (pid_to_ptid (GET_LWP (lp->ptid)),
+ lp->step, signo);
+
lp->stopped = 0;
status = 0;
goto retry;
@@ -931,24 +970,36 @@ kill_wait_callback (struct lwp_info *lp,
static void
lin_lwp_kill (void)
{
+ struct target_ops *process_ops;
+
/* Kill all LWP's ... */
iterate_over_lwps (kill_callback, NULL);
/* ... and wait until we've flushed all events. */
iterate_over_lwps (kill_wait_callback, NULL);
- target_mourn_inferior ();
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_mourn_inferior)!=NULL)
+ (process_ops->to_mourn_inferior) ();
}
static void
lin_lwp_create_inferior (char *exec_file, char *allargs, char **env)
{
- child_ops.to_create_inferior (exec_file, allargs, env);
+ struct target_ops *process_ops;
+
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_create_inferior)!=NULL)
+ (process_ops->to_create_inferior) (exec_file, allargs, env);
}
-static void
+static void
lin_lwp_mourn_inferior (void)
{
+ struct target_ops *process_ops;
+
trap_ptid = null_ptid;
/* Destroy LWP info; it's no longer valid. */
@@ -958,18 +1009,25 @@ lin_lwp_mourn_inferior (void)
sigprocmask (SIG_SETMASK, &normal_mask, NULL);
sigemptyset (&blocked_mask);
- child_ops.to_mourn_inferior ();
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_mourn_inferior)!=NULL)
+ (process_ops->to_mourn_inferior) ();
}
static void
lin_lwp_fetch_registers (int regno)
{
+ struct target_ops *process_ops;
struct cleanup *old_chain = save_inferior_ptid ();
if (is_lwp (inferior_ptid))
inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
- fetch_inferior_registers (regno);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_fetch_registers)!=NULL)
+ (process_ops->to_fetch_registers) (regno);
do_cleanups (old_chain);
}
@@ -977,12 +1035,16 @@ lin_lwp_fetch_registers (int regno)
static void
lin_lwp_store_registers (int regno)
{
+ struct target_ops *process_ops;
struct cleanup *old_chain = save_inferior_ptid ();
if (is_lwp (inferior_ptid))
inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
- store_inferior_registers (regno);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_store_registers)!=NULL)
+ (process_ops->to_store_registers) (regno);
do_cleanups (old_chain);
}
@@ -992,13 +1054,17 @@ lin_lwp_xfer_memory (CORE_ADDR memaddr,
struct mem_attrib *attrib,
struct target_ops *target)
{
+ struct target_ops *process_ops;
struct cleanup *old_chain = save_inferior_ptid ();
- int xfer;
+ int xfer = 0;
if (is_lwp (inferior_ptid))
inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
- xfer = child_xfer_memory (memaddr, myaddr, len, write, attrib, target);
+ process_ops = get_target_below ();
+ if (process_ops!=NULL)
+ if ((process_ops->to_xfer_memory)!=NULL)
+ xfer = (process_ops->to_xfer_memory) (memaddr, myaddr, len, write, attrib, target);
do_cleanups (old_chain);
return xfer;
@@ -1160,4 +1226,53 @@ lin_thread_get_thread_signals (sigset_t
/* ... except during a sigsuspend. */
sigdelset (&suspend_mask, cancel);
+}
+
+/* FIXME: I truely should use a target stack macro/function
+ that returns the next lower target that has a non-NULL
+ pointer in a given function pointer. What if a new
+ stratum is added just above the process_stratum? Should
+ the process_stratum or the new stratum's function be called.
+ I think in general that it should be the next lower startum
+ that has the non-NULL given function pointer. This is a
+ job for a portable C coding wizard.
+ John S. Kallal 2001-MAY-18 */
+
+
+/* FIXME: Maybe function find_target_stratum should go
+ into the target.c file? But for now only this file needs
+ this function. Better yet, put the lwp-layer target into
+ the target stack. John S. Kallal 2001-MAY-18 */
+
+/* Find a single target at the given stratum level in the
+ target stack and return a pointer to it. If there is no
+ target at the given stratum level in the target stack,
+ return NULL. */
+
+static struct target_ops *
+find_target_stratum (enum strata level)
+{
+ struct target_stack_item *cur;
+
+ for (cur = target_stack; cur; cur = cur->next)
+ {
+ if (cur->target_ops->to_stratum == level)
+ return cur->target_ops;
+ }
+
+ return NULL;
+}
+
+/* Find the target below the thread_stratum
+ (i.e process_stratum). This is needed because
+ currently the lwp-layer is NOT stacked. */
+
+static struct target_ops *
+get_target_below (void)
+{
+ struct target_ops *process_ops;
+
+ process_ops = find_target_stratum( process_stratum );
+
+ return process_ops;
}