From mboxrd@z Thu Jan 1 00:00:00 1970 From: John S. Kallal To: gdb-patches@sources.redhat.com, kettenis@science.uva.nl Cc: Michael Snyder Subject: [PATCH RFC] Make lin-lwp.c functions use target vectors, 3rd try Date: Tue, 22 May 2001 20:45:00 -0000 Message-id: <01052223475203.01552@CyberMax> X-SW-Source: 2001-05/msg00429.html 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 * 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; }