aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-low.h
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-12-29 19:41:07 +0000
committerPedro Alves <palves@redhat.com>2015-01-09 14:42:32 +0000
commit582511be69deb0e9d52efd6d51f860b6bee02a64 (patch)
tree3a79e3d349e693ba3b1d1247f532d9d101de20d5 /gdb/gdbserver/linux-low.h
parent9c02b52532ac7864e7e19c7df1fb2e63625f3131 (diff)
downloadgdb-582511be69deb0e9d52efd6d51f860b6bee02a64.zip
gdb-582511be69deb0e9d52efd6d51f860b6bee02a64.tar.gz
gdb-582511be69deb0e9d52efd6d51f860b6bee02a64.tar.bz2
[gdbserver] linux-low.c: better starvation avoidance, handle non-stop mode too
This patch applies the same starvation avoidance improvements of the previous patch to the Linux gdbserver side. Without this, the test added by the following commit (gdb.threads/non-stop-fair-events.exp) always fails with time outs. gdb/gdbserver/ 2015-01-09 Pedro Alves <palves@redhat.com> * linux-low.c (step_over_bkpt): Move higher up in the file. (handle_extended_wait): Don't store the stop_pc here. (get_stop_pc): Adjust comments and rename to ... (check_stopped_by_breakpoint): ... this. Record whether the LWP stopped for a software breakpoint or hardware breakpoint. (thread_still_has_status_pending_p): New function. (status_pending_p_callback): Use thread_still_has_status_pending_p. If the event is no longer interesting, resume the LWP. (handle_tracepoints): Add assert. (maybe_move_out_of_jump_pad): Remove cancel_breakpoints call. (wstatus_maybe_breakpoint): New function. (cancel_breakpoint): Delete function. (check_stopped_by_watchpoint): New function, factored out from linux_low_filter_event. (lp_status_maybe_breakpoint): Delete function. (linux_low_filter_event): Remove filter_ptid argument. Leave thread group exits pending here. Store the LWP's stop PC. Always leave events pending. (linux_wait_for_event_filtered): Pull all events out of the kernel, and leave them all pending. (count_events_callback, select_event_lwp_callback): Consider all events. (cancel_breakpoints_callback, linux_cancel_breakpoints): Delete. (select_event_lwp): Only give preference to the stepping LWP in all-stop mode. Adjust comments. (ignore_event): New function. (linux_wait_1): Delete 'retry' label. Use ignore_event. Remove references to cancel_breakpoints. Adjust to renames. Also give equal priority to all LWPs that have had events in non-stop mode. If reporting a software breakpoint event, unadjust the LWP's PC. (linux_wait): If linux_wait_1 returned an ignored event, retry. (stuck_in_jump_pad_callback, move_out_of_jump_pad_callback): Adjust. (linux_resume_one_lwp): Store the LWP's PC. Adjust. (resume_status_pending_p): Use thread_still_has_status_pending_p. (linux_stopped_by_watchpoint): Adjust. (linux_target_ops): Remove reference to linux_cancel_breakpoints. * linux-low.h (enum lwp_stop_reason): New. (struct lwp_info) <stop_pc>: Adjust comment. <stopped_by_watchpoint>: Delete field. <stop_reason>: New field. * linux-x86-low.c (x86_linux_prepare_to_resume): Adjust. * mem-break.c (software_breakpoint_inserted_here) (hardware_breakpoint_inserted_here): New function. * mem-break.h (software_breakpoint_inserted_here) (hardware_breakpoint_inserted_here): Declare. * target.h (struct target_ops) <cancel_breakpoints>: Remove field. (cancel_breakpoints): Delete. * tracepoint.c (clear_installed_tracepoints, stop_tracing) (upload_fast_traceframes): Remove references to cancel_breakpoints.
Diffstat (limited to 'gdb/gdbserver/linux-low.h')
-rw-r--r--gdb/gdbserver/linux-low.h29
1 files changed, 24 insertions, 5 deletions
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 97b163f..bea4a37 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -230,6 +230,24 @@ extern struct linux_target_ops the_low_target;
#define get_thread_lwp(thr) ((struct lwp_info *) (inferior_target_data (thr)))
#define get_lwp_thread(lwp) ((lwp)->thread)
+/* Reasons an LWP last stopped. */
+
+enum lwp_stop_reason
+{
+ /* Either not stopped, or stopped for a reason that doesn't require
+ special tracking. */
+ LWP_STOPPED_BY_NO_REASON,
+
+ /* Stopped by a software breakpoint. */
+ LWP_STOPPED_BY_SW_BREAKPOINT,
+
+ /* Stopped by a hardware breakpoint. */
+ LWP_STOPPED_BY_HW_BREAKPOINT,
+
+ /* Stopped by a watchpoint. */
+ LWP_STOPPED_BY_WATCHPOINT
+};
+
/* This struct is recorded in the target_data field of struct thread_info.
On linux ``all_threads'' is keyed by the LWP ID, which we use as the
@@ -269,8 +287,9 @@ struct lwp_info
/* When stopped is set, the last wait status recorded for this lwp. */
int last_status;
- /* When stopped is set, this is where the lwp stopped, with
- decr_pc_after_break already accounted for. */
+ /* When stopped is set, this is where the lwp last stopped, with
+ decr_pc_after_break already accounted for. If the LWP is
+ running, this is the address at which the lwp was resumed. */
CORE_ADDR stop_pc;
/* If this flag is set, STATUS_PENDING is a waitstatus that has not yet
@@ -278,9 +297,9 @@ struct lwp_info
int status_pending_p;
int status_pending;
- /* STOPPED_BY_WATCHPOINT is non-zero if this LWP stopped with a data
- watchpoint trap. */
- int stopped_by_watchpoint;
+ /* The reason the LWP last stopped, if we need to track it
+ (breakpoint, watchpoint, etc.) */
+ enum lwp_stop_reason stop_reason;
/* On architectures where it is possible to know the data address of
a triggered watchpoint, STOPPED_DATA_ADDRESS is non-zero, and