diff options
Diffstat (limited to 'gdb/linux-nat.c')
-rw-r--r-- | gdb/linux-nat.c | 67 |
1 files changed, 61 insertions, 6 deletions
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 19b4b57..1cbfc44 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -175,7 +175,10 @@ static struct target_ops *linux_ops; static struct target_ops linux_ops_saved; /* The method to call, if any, when a new thread is attached. */ -static void (*linux_nat_new_thread) (ptid_t); +static void (*linux_nat_new_thread) (struct lwp_info *); + +/* Hook to call prior to resuming a thread. */ +static void (*linux_nat_prepare_to_resume) (struct lwp_info *); /* The method to call, if any, when the siginfo object needs to be converted between the layout returned by ptrace, and the layout in @@ -1073,6 +1076,15 @@ status_to_str (int status) return buf; } +/* Destroy and free LP. */ + +static void +lwp_free (struct lwp_info *lp) +{ + xfree (lp->arch_private); + xfree (lp); +} + /* Remove all LWPs belong to PID from the lwp list. */ static void @@ -1093,7 +1105,7 @@ purge_lwp_list (int pid) else lpprev->next = lp->next; - xfree (lp); + lwp_free (lp); } else lpprev = lp; @@ -1139,8 +1151,8 @@ add_lwp (ptid_t ptid) lp->next = lwp_list; lwp_list = lp; - if (num_lwps (GET_PID (ptid)) > 1 && linux_nat_new_thread != NULL) - linux_nat_new_thread (ptid); + if (linux_nat_new_thread != NULL) + linux_nat_new_thread (lp); return lp; } @@ -1166,7 +1178,7 @@ delete_lwp (ptid_t ptid) else lwp_list = lp->next; - xfree (lp); + lwp_free (lp); } /* Return a pointer to the structure describing the LWP corresponding @@ -1724,6 +1736,8 @@ detach_callback (struct lwp_info *lp, void *data) /* Pass on any pending signal for this LWP. */ get_pending_status (lp, &status); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); errno = 0; if (ptrace (PTRACE_DETACH, GET_LWP (lp->ptid), 0, WSTOPSIG (status)) < 0) @@ -1784,6 +1798,8 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty) target_pid_to_str (main_lwp->ptid)); } + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (main_lwp); delete_lwp (main_lwp->ptid); if (forks_exist_p ()) @@ -1825,6 +1841,8 @@ resume_lwp (struct lwp_info *lp, int step) "RC: PTRACE_CONT %s, 0, 0 (resuming sibling)\n", target_pid_to_str (lp->ptid)); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), step, TARGET_SIGNAL_0); @@ -1969,6 +1987,8 @@ linux_nat_resume (struct target_ops *ops, /* Convert to something the lower layer understands. */ ptid = pid_to_ptid (GET_LWP (lp->ptid)); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, ptid, step, signo); memset (&lp->siginfo, 0, sizeof (lp->siginfo)); lp->stopped_by_watchpoint = 0; @@ -2138,6 +2158,8 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) /* Note that gdbarch_get_syscall_number may access registers, hence fill a regcache. */ registers_changed (); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), lp->step, TARGET_SIGNAL_0); return 1; @@ -2325,6 +2347,8 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, fprintf_unfiltered (gdb_stdlog, "LHEW: resuming new LWP %ld\n", GET_LWP (new_lp->ptid)); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (new_lp); linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid), 0, TARGET_SIGNAL_0); new_lp->stopped = 0; @@ -2334,6 +2358,8 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, if (debug_linux_nat) fprintf_unfiltered (gdb_stdlog, "LHEW: resuming parent LWP %d\n", pid); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), 0, TARGET_SIGNAL_0); @@ -2597,6 +2623,14 @@ stop_callback (struct lwp_info *lp, void *data) return 0; } +/* Request a stop on LWP. */ + +void +linux_stop_lwp (struct lwp_info *lwp) +{ + stop_callback (lwp, NULL); +} + /* Return non-zero if LWP PID has a pending SIGINT. */ static int @@ -3333,6 +3367,8 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) registers_changed (); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), lp->step, TARGET_SIGNAL_0); if (debug_linux_nat) @@ -3364,6 +3400,8 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p) lp->ignore_sigint = 0; registers_changed (); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), lp->step, TARGET_SIGNAL_0); if (debug_linux_nat) @@ -3538,6 +3576,8 @@ retry: /* Resume the thread. It should halt immediately returning the pending SIGSTOP. */ registers_changed (); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), lp->step, TARGET_SIGNAL_0); if (debug_linux_nat) @@ -3787,6 +3827,8 @@ retry: newly attached threads may cause an unwanted delay in getting them running. */ registers_changed (); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo); if (debug_linux_nat) @@ -3943,6 +3985,8 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, void *data) lp->step); registers_changed (); + if (linux_nat_prepare_to_resume != NULL) + linux_nat_prepare_to_resume (lp); linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)), lp->step, TARGET_SIGNAL_0); lp->stopped = 0; @@ -5840,7 +5884,8 @@ linux_nat_add_target (struct target_ops *t) /* Register a method to call whenever a new thread is attached. */ void -linux_nat_set_new_thread (struct target_ops *t, void (*new_thread) (ptid_t)) +linux_nat_set_new_thread (struct target_ops *t, + void (*new_thread) (struct lwp_info *)) { /* Save the pointer. We only support a single registered instance of the GNU/Linux native target, so we do not need to map this to @@ -5861,6 +5906,16 @@ linux_nat_set_siginfo_fixup (struct target_ops *t, linux_nat_siginfo_fixup = siginfo_fixup; } +/* Register a method to call prior to resuming a thread. */ + +void +linux_nat_set_prepare_to_resume (struct target_ops *t, + void (*prepare_to_resume) (struct lwp_info *)) +{ + /* Save the pointer. */ + linux_nat_prepare_to_resume = prepare_to_resume; +} + /* Return the saved siginfo associated with PTID. */ struct siginfo * linux_nat_get_siginfo (ptid_t ptid) |