diff options
author | Pedro Alves <palves@redhat.com> | 2011-12-14 17:20:32 +0000 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2011-12-14 17:20:32 +0000 |
commit | 7b50312ad68f7c3acac2b318f6ff96956ad381ea (patch) | |
tree | 8334359a21c6cfe3384baa3bb625a28db9ace8c7 /gdb/linux-nat.c | |
parent | 0d13c96b214428affc33281d6d119a873c45acee (diff) | |
download | gdb-7b50312ad68f7c3acac2b318f6ff96956ad381ea.zip gdb-7b50312ad68f7c3acac2b318f6ff96956ad381ea.tar.gz gdb-7b50312ad68f7c3acac2b318f6ff96956ad381ea.tar.bz2 |
gdb/
2011-12-14 Pedro Alves <pedro@codesourcery.com>
PR threads/10729
* linux-nat.c (linux_nat_new_thread): Change parameter to an lwp
pointer.
(linux_nat_prepare_to_resume): New global.
(lwp_free): New.
(purge_lwp_list): Use it.
(add_lwp): Call linux_nat_new_thread even on the first LWP.
Adjust to interface change.
(delete_lwp): Call lwp_free instead of xfree.
(detach_callback, linux_nat_detach, resume_lwp, linux_nat_resume)
(linux_handle_syscall_trap, linux_handle_extended_wait)
(linux_nat_filter_event, resume_stopped_resumed_lwps): Call
linux_nat_prepare_to_resume before resuming.
(linux_stop_lwp): New.
(linux_nat_set_new_thread): Adjust.
(linux_nat_set_prepare_to_resume): New.
* linux-nat.h (struct arch_lwp_info): Forward declare.
(struct lwp_info) <arch_private>: New field.
(linux_stop_lwp): Declare.
(linux_nat_set_new_thread): Adjust.
(linux_nat_set_prepare_to_resume): New.
* i386-nat.c (DR_NADDR, DR_STATUS, DR_CONTROL)
(struct i386_debug_reg_state): Move to i386-nat.h.
(dr_mirror): Comment.
(i386_debug_reg_state): New.
(i386_update_inferior_debug_regs): Simplify.
(i386_stopped_data_address): Use the debug register state from the
inferior, not from the local cache.
* i386-nat.h (struct i386_dr_low_type): Delete reset_addr and
unset_status fields. New get_addr and get_control fields.
(DR_FIRSTADDR, DR_LASTADDR, DR_CONTROL): Moved from i386-nat.c.
(DR_NADDR, DR_STATUS): New.
(struct i386_debug_reg_state): Moved from i386-nat.c.
* amd64-linux-nat.c (struct arch_lwp_info): New.
(amd64_linux_dr): Delete global.
(amd64_linux_dr_get_addr): New.
(amd64_linux_dr_get_control): New.
(amd64_linux_dr_unset_status): Delete.
(amd64_linux_dr_set_addr): Reimplement.
(amd64_linux_dr_reset_addr): Delete.
(update_debug_registers_callback): New.
(amd64_linux_dr_set_control): Reimplement.
(amd64_linux_dr_set_addr): Reimplement.
(amd64_linux_prepare_to_resume): New.
(amd64_linux_new_thread): Change parameter to an lwp pointer.
Reimplement.
(_initialize_amd64_linux_nat): No longer install
i386_dr_low.reset_addr and i386_dr_low.unset_status. Install
amd64_linux_dr_get_control as i386_dr_low.get_control. Install
amd64_linux_dr_get_addr as i386_dr_low.get_addr. Install
amd64_linux_prepare_to_resume.
* i386-linux-nat.c (DR_FIRSTADDR, DR_LASTADDR, DR_STATUS)
(DR_CONTROL): Delete.
(struct arch_lwp_info): New.
(i386_linux_dr): Delete global.
(i386_linux_dr_set_control): Reimplement.
(i386_linux_dr_get_addr): New.
(i386_linux_dr_set_addr): Reimplement.
(i386_linux_dr_get_control): New.
(update_debug_registers_callback): New.
(i386_linux_dr_unset_status): Delete.
(i386_linux_dr_set_addr): Reimplement.
(i386_linux_prepare_to_resume): New.
(i386_linux_new_thread): Change parameter to an lwp pointer.
Reimplement.
(_initialize_i386_linux_nat): No longer install
i386_dr_low.reset_addr and i386_dr_low.unset_status. Install
i386_linux_dr_get_control as i386_dr_low.get_control. Install
i386_linux_dr_get_addr as i386_dr_low.get_addr. Install
i386_linux_prepare_to_resume.
* arm-linux-nat.c (arm_linux_new_thread): Change parameter to an
lwp pointer. Adjust.
* ia64-linux-nat.c (ia64_linux_new_thread): Likewise.
* mips-linux-nat.c (mips_linux_new_thread): Likewise.
* ppc-linux-nat.c (ppc_linux_new_thread): Likewise.
* s390-nat.c (s390_fix_watch_points): Likewise.
* i386-darwin-nat.c (DR_FIRSTADDR, DR_LASTADDR, DR_STATUS)
(DR_CONTROL): Delete.
(i386_darwin_dr_reset_addr): Delete.
(i386_darwin_dr_get_addr): New.
(i386_darwin_dr_get_control): New.
* go32-nat.c
(go32_get_dr7, go32_get_dr): New.
(init_go32_ops): No longer install i386_dr_low.reset_addr.
Install go32_get_dr7 as i386_dr_low.get_control. Install
go32_get_dr as i386_dr_low.get_addr.
* i386bsd-nat.c (i386bsd_dr_get): New.
(i386bsd_dr_reset_addr): Delete.
(i386bsd_dr_get_addr): New.
(i386bsd_dr_get_status): Use i386bsd_dr_get.
(i386bsd_dr_get_control): New.
* i386bsd-nat.h (i386bsd_dr_reset_addr): Delete.
(i386bsd_dr_get_addr): New.
(i386bsd_dr_get_control): New.
* i386fbsd-nat.c (_initialize_i386fbsd_nat): No longer install
i386_dr_low.reset_addr and i386_dr_low.unset_status. Install
i386bsd_dr_get_control as i386_dr_low.get_control. Install
i386bsd_dr_get_addr as i386_dr_low.get_addr.
* windows-nat.c (init_windows_ops): No longer install
i386_dr_low.reset_addr and i386_dr_low.unset_status. Install
cygwin_get_dr7 as i386_dr_low.get_control. Install cygwin_get_dr
as i386_dr_low.get_addr.
(cygwin_get_dr): New.
(cygwin_get_dr7): New.
gdb/testsuite/
2011-12-14 Pedro Alves <pedro@codesourcery.com>
PR threads/10729
* gdb.mi/watch-nonstop.c: New file.
* gdb.mi/mi-watch-nonstop.exp: New file.
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) |