[PATCH RFC] Make lin-lwp.c functions use target vectors

John S. Kallal kallal@home.com
Fri May 18 17:50:00 GMT 2001


	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, the lin-lwp.c code still does 
	many system calls and other calls that do not go through
	the target stack.

	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?  
	

2001-05-18  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	Wed May 16 12:03:55 2001
+++ gdb/lin-lwp.c	Fri May 18 09:36:32 2001
@@ -117,9 +117,11 @@ ptid_t trap_ptid;
 /* This module's target-specific operations.  */
 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
    the WNOHANG flag and call waitpid in a loop.  To optimize
@@ -143,8 +145,9 @@ 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
    what GDB's generic threads layer does for its thread list,
@@ -333,12 +336,16 @@ lin_lwp_attach_lwp (ptid_t ptid, int ver
 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)));
 
@@ -391,8 +398,10 @@ 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.  */
   gdb_assert (num_lwps == 1);
@@ -406,9 +415,13 @@ lin_lwp_detach (char *args, int from_tty
   sigprocmask (SIG_SETMASK, &normal_mask, NULL);
   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);
 }
 
 
 struct private_thread_info
@@ -434,8 +447,10 @@ 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;
 
@@ -459,9 +474,14 @@ resume_callback (struct lwp_info *lp, vo
 	  tp->step_range_start = tp->step_range_end = 0;
 	}
 #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;
     }
 
@@ -470,8 +490,9 @@ 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;
 
   /* Apparently the interpretation of PID is dependent on STEP: If
@@ -510,9 +531,12 @@ 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);
 }
 
 
 /* Send a SIGSTOP to LP.  */
@@ -652,8 +676,9 @@ 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;
   pid_t pid = PIDGET (ptid);
@@ -726,10 +751,14 @@ lin_lwp_wait (ptid_t ptid, struct target
 	 single-stepping LWP A.  */
 
       /* 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.  */
       stop_wait_callback (lp, NULL);
@@ -812,10 +841,14 @@ 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.  */
 	      status = 0;
@@ -858,9 +891,15 @@ lin_lwp_wait (ptid_t ptid, struct target
       if (signal_stop_state (signo) == 0
 	  && 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;
 	}
@@ -930,26 +969,38 @@ 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.  */
   init_lwp_list ();
@@ -957,33 +1008,44 @@ lin_lwp_mourn_inferior (void)
   /* Restore the original signal mask.  */
   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);
 }
 
 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);
 }
 
@@ -991,15 +1053,19 @@ static int
 lin_lwp_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write,
 		     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;
 }
@@ -1159,5 +1225,61 @@ lin_thread_get_thread_signals (sigset_t 
   sigprocmask (SIG_BLOCK, &blocked_mask, NULL);
 
   /* ... 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's 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() this 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;
 }



More information about the Gdb-patches mailing list