diff options
Diffstat (limited to 'gdbserver/linux-low.cc')
-rw-r--r-- | gdbserver/linux-low.cc | 132 |
1 files changed, 64 insertions, 68 deletions
diff --git a/gdbserver/linux-low.cc b/gdbserver/linux-low.cc index 6ea517e..b6820ad 100644 --- a/gdbserver/linux-low.cc +++ b/gdbserver/linux-low.cc @@ -450,7 +450,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, struct thread_info *event_thr = get_lwp_thread (event_lwp); struct lwp_info *new_lwp; - gdb_assert (event_lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE); + gdb_assert (event_lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE); /* All extended events we currently use are mid-syscall. Only PTRACE_EVENT_STOP is delivered more like a signal-stop, but @@ -515,7 +515,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, child_lwp->status_pending_p = 0; child_thr = get_lwp_thread (child_lwp); child_thr->last_resume_kind = resume_stop; - child_thr->last_status.kind = TARGET_WAITKIND_STOPPED; + child_thr->last_status.set_stopped (GDB_SIGNAL_0); /* If we're suspending all threads, leave this one suspended too. If the fork/clone parent is stepping over a breakpoint, @@ -554,11 +554,9 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, /* Save fork info in the parent thread. */ if (event == PTRACE_EVENT_FORK) - event_lwp->waitstatus.kind = TARGET_WAITKIND_FORKED; + event_lwp->waitstatus.set_forked (ptid); else if (event == PTRACE_EVENT_VFORK) - event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORKED; - - event_lwp->waitstatus.value.related_pid = ptid; + event_lwp->waitstatus.set_vforked (ptid); /* The status_pending field contains bits denoting the extended event, so when the pending event is handled, @@ -625,7 +623,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, } else if (cs.report_thread_events) { - new_lwp->waitstatus.kind = TARGET_WAITKIND_THREAD_CREATED; + new_lwp->waitstatus.set_thread_created (); new_lwp->status_pending_p = 1; new_lwp->status_pending = status; } @@ -639,7 +637,7 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, } else if (event == PTRACE_EVENT_VFORK_DONE) { - event_lwp->waitstatus.kind = TARGET_WAITKIND_VFORK_DONE; + event_lwp->waitstatus.set_vfork_done (); if (event_lwp->bp_reinsert != 0 && supports_software_single_step ()) { @@ -684,16 +682,16 @@ linux_process_target::handle_extended_wait (lwp_info **orig_event_lwp, arch_setup_thread (event_thr); /* Set the event status. */ - event_lwp->waitstatus.kind = TARGET_WAITKIND_EXECD; - event_lwp->waitstatus.value.execd_pathname - = xstrdup (linux_proc_pid_to_exec_file (lwpid_of (event_thr))); + event_lwp->waitstatus.set_execd + (make_unique_xstrdup + (linux_proc_pid_to_exec_file (lwpid_of (event_thr)))); /* Mark the exec status as pending. */ event_lwp->stopped = 1; event_lwp->status_pending_p = 1; event_lwp->status_pending = wstat; event_thr->last_resume_kind = resume_continue; - event_thr->last_status.kind = TARGET_WAITKIND_IGNORE; + event_thr->last_status.set_ignore (); /* Update syscall state in the new lwp, effectively mid-syscall too. */ event_lwp->syscall_state = TARGET_WAITKIND_SYSCALL_ENTRY; @@ -1388,8 +1386,8 @@ get_detach_signal (struct thread_info *thread) /* If the thread had been suspended by gdbserver, and it stopped cleanly, then it'll have stopped with SIGSTOP. But we don't want to deliver that SIGSTOP. */ - if (thread->last_status.kind != TARGET_WAITKIND_STOPPED - || thread->last_status.value.sig == GDB_SIGNAL_0) + if (thread->last_status.kind () != TARGET_WAITKIND_STOPPED + || thread->last_status.sig () == GDB_SIGNAL_0) return 0; /* Otherwise, we may need to deliver the signal we @@ -1712,7 +1710,7 @@ lwp_resumed (struct lwp_info *lwp) corresponding stop to gdb yet? If so, the thread is still resumed/running from gdb's perspective. */ if (thread->last_resume_kind == resume_stop - && thread->last_status.kind == TARGET_WAITKIND_IGNORE) + && thread->last_status.kind () == TARGET_WAITKIND_IGNORE) return 1; return 0; @@ -2464,7 +2462,7 @@ linux_process_target::resume_stopped_resumed_lwps (thread_info *thread) if (lp->stopped && !lp->suspended && !lp->status_pending_p - && thread->last_status.kind == TARGET_WAITKIND_IGNORE) + && thread->last_status.kind () == TARGET_WAITKIND_IGNORE) { int step = 0; @@ -2710,7 +2708,7 @@ select_event_lwp (struct lwp_info **orig_lp) { lwp_info *lp = get_thread_lwp (thread); - return (thread->last_status.kind == TARGET_WAITKIND_IGNORE + return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE && thread->last_resume_kind == resume_step && lp->status_pending_p); }); @@ -2732,7 +2730,7 @@ select_event_lwp (struct lwp_info **orig_lp) lwp_info *lp = get_thread_lwp (thread); /* Only resumed LWPs that have an event pending. */ - return (thread->last_status.kind == TARGET_WAITKIND_IGNORE + return (thread->last_status.kind () == TARGET_WAITKIND_IGNORE && lp->status_pending_p); }); } @@ -2831,17 +2829,17 @@ linux_process_target::stabilize_threads () over internal breakpoints and such. */ wait_1 (minus_one_ptid, &ourstatus, 0); - if (ourstatus.kind == TARGET_WAITKIND_STOPPED) + if (ourstatus.kind () == TARGET_WAITKIND_STOPPED) { lwp = get_thread_lwp (current_thread); /* Lock it. */ lwp_suspended_inc (lwp); - if (ourstatus.value.sig != GDB_SIGNAL_0 + if (ourstatus.sig () != GDB_SIGNAL_0 || current_thread->last_resume_kind == resume_stop) { - wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.value.sig)); + wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.sig ())); enqueue_one_deferred_signal (lwp, &wstat); } } @@ -2877,7 +2875,7 @@ ignore_event (struct target_waitstatus *ourstatus) another target_wait call. */ async_file_mark (); - ourstatus->kind = TARGET_WAITKIND_IGNORE; + ourstatus->set_ignore (); return null_ptid; } @@ -2892,9 +2890,9 @@ linux_process_target::filter_exit_event (lwp_info *event_child, if (!last_thread_of_process_p (pid_of (thread))) { if (cs.report_thread_events) - ourstatus->kind = TARGET_WAITKIND_THREAD_EXITED; + ourstatus->set_thread_exited (0); else - ourstatus->kind = TARGET_WAITKIND_IGNORE; + ourstatus->set_ignore (); delete_lwp (event_child); } @@ -2965,7 +2963,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, bp_explains_trap = 0; trace_event = 0; in_step_range = 0; - ourstatus->kind = TARGET_WAITKIND_IGNORE; + ourstatus->set_ignore (); auto status_pending_p_any = [&] (thread_info *thread) { @@ -3006,7 +3004,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, debug_exit (); } - ourstatus->kind = TARGET_WAITKIND_IGNORE; + ourstatus->set_ignore (); return null_ptid; } else if (pid == -1) @@ -3018,7 +3016,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, debug_exit (); } - ourstatus->kind = TARGET_WAITKIND_NO_RESUMED; + ourstatus->set_no_resumed (); return null_ptid; } @@ -3030,8 +3028,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, { if (WIFEXITED (w)) { - ourstatus->kind = TARGET_WAITKIND_EXITED; - ourstatus->value.integer = WEXITSTATUS (w); + ourstatus->set_exited (WEXITSTATUS (w)); if (debug_threads) { @@ -3044,8 +3041,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, } else { - ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w)); + ourstatus->set_signalled (gdb_signal_from_host (WTERMSIG (w))); if (debug_threads) { @@ -3057,7 +3053,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, } } - if (ourstatus->kind == TARGET_WAITKIND_EXITED) + if (ourstatus->kind () == TARGET_WAITKIND_EXITED) return filter_exit_event (event_child, ourstatus); return ptid_of (current_thread); @@ -3252,8 +3248,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, if (stabilizing_threads) { - ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = GDB_SIGNAL_0; + ourstatus->set_stopped (GDB_SIGNAL_0); if (debug_threads) { @@ -3378,7 +3373,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, || (gdb_breakpoint_here (event_child->stop_pc) && gdb_condition_true_at_breakpoint (event_child->stop_pc) && gdb_no_commands_at_breakpoint (event_child->stop_pc)) - || event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE); + || event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE); run_breakpoint_commands (event_child->stop_pc); @@ -3448,7 +3443,7 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, if (debug_threads) { - if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE) + if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE) { std::string str = target_waitstatus_to_string (&event_child->waitstatus); @@ -3589,14 +3584,14 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, unstop_all_lwps (1, event_child); } - if (event_child->waitstatus.kind != TARGET_WAITKIND_IGNORE) + if (event_child->waitstatus.kind () != TARGET_WAITKIND_IGNORE) { /* If the reported event is an exit, fork, vfork or exec, let GDB know. */ /* Break the unreported fork relationship chain. */ - if (event_child->waitstatus.kind == TARGET_WAITKIND_FORKED - || event_child->waitstatus.kind == TARGET_WAITKIND_VFORKED) + if (event_child->waitstatus.kind () == TARGET_WAITKIND_FORKED + || event_child->waitstatus.kind () == TARGET_WAITKIND_VFORKED) { event_child->fork_relative->fork_relative = NULL; event_child->fork_relative = NULL; @@ -3604,10 +3599,13 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, *ourstatus = event_child->waitstatus; /* Clear the event lwp's waitstatus since we handled it already. */ - event_child->waitstatus.kind = TARGET_WAITKIND_IGNORE; + event_child->waitstatus.set_ignore (); } else - ourstatus->kind = TARGET_WAITKIND_STOPPED; + { + /* The actual stop signal is overwritten below. */ + ourstatus->set_stopped (GDB_SIGNAL_0); + } /* Now that we've selected our final event LWP, un-adjust its PC if it was a software breakpoint, and the client doesn't know we can @@ -3627,9 +3625,15 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, if (WSTOPSIG (w) == SYSCALL_SIGTRAP) { - get_syscall_trapinfo (event_child, - &ourstatus->value.syscall_number); - ourstatus->kind = event_child->syscall_state; + int syscall_number; + + get_syscall_trapinfo (event_child, &syscall_number); + if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY) + ourstatus->set_syscall_entry (syscall_number); + else if (event_child->syscall_state == TARGET_WAITKIND_SYSCALL_RETURN) + ourstatus->set_syscall_return (syscall_number); + else + gdb_assert_not_reached ("unexpected syscall state"); } else if (current_thread->last_resume_kind == resume_stop && WSTOPSIG (w) == SIGSTOP) @@ -3637,19 +3641,17 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, /* A thread that has been requested to stop by GDB with vCont;t, and it stopped cleanly, so report as SIG0. The use of SIGSTOP is an implementation detail. */ - ourstatus->value.sig = GDB_SIGNAL_0; + ourstatus->set_stopped (GDB_SIGNAL_0); } else if (current_thread->last_resume_kind == resume_stop && WSTOPSIG (w) != SIGSTOP) { /* A thread that has been requested to stop by GDB with vCont;t, but, it stopped for other reasons. */ - ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w)); - } - else if (ourstatus->kind == TARGET_WAITKIND_STOPPED) - { - ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w)); + ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w))); } + else if (ourstatus->kind () == TARGET_WAITKIND_STOPPED) + ourstatus->set_stopped (gdb_signal_from_host (WSTOPSIG (w))); gdb_assert (step_over_bkpt == null_ptid); @@ -3657,11 +3659,11 @@ linux_process_target::wait_1 (ptid_t ptid, target_waitstatus *ourstatus, { debug_printf ("wait_1 ret = %s, %d, %d\n", target_pid_to_str (ptid_of (current_thread)), - ourstatus->kind, ourstatus->value.sig); + ourstatus->kind (), ourstatus->sig ()); debug_exit (); } - if (ourstatus->kind == TARGET_WAITKIND_EXITED) + if (ourstatus->kind () == TARGET_WAITKIND_EXITED) return filter_exit_event (event_child, ourstatus); return ptid_of (current_thread); @@ -3712,7 +3714,7 @@ linux_process_target::wait (ptid_t ptid, } while ((target_options & TARGET_WNOHANG) == 0 && event_ptid == null_ptid - && ourstatus->kind == TARGET_WAITKIND_IGNORE); + && ourstatus->kind () == TARGET_WAITKIND_IGNORE); /* If at least one stop was reported, there may be more. A single SIGCHLD can signal more than one child stop. */ @@ -3813,15 +3815,9 @@ mark_lwp_dead (struct lwp_info *lwp, int wstat) /* Store in waitstatus as well, as there's nothing else to process for this event. */ if (WIFEXITED (wstat)) - { - lwp->waitstatus.kind = TARGET_WAITKIND_EXITED; - lwp->waitstatus.value.integer = WEXITSTATUS (wstat); - } + lwp->waitstatus.set_exited (WEXITSTATUS (wstat)); else if (WIFSIGNALED (wstat)) - { - lwp->waitstatus.kind = TARGET_WAITKIND_SIGNALLED; - lwp->waitstatus.value.sig = gdb_signal_from_host (WTERMSIG (wstat)); - } + lwp->waitstatus.set_signalled (gdb_signal_from_host (WTERMSIG (wstat))); /* Prevent trying to stop it. */ lwp->stopped = 1; @@ -4087,7 +4083,7 @@ linux_process_target::resume_one_lwp_throw (lwp_info *lwp, int step, if (lwp->stopped == 0) return; - gdb_assert (lwp->waitstatus.kind == TARGET_WAITKIND_IGNORE); + gdb_assert (lwp->waitstatus.kind () == TARGET_WAITKIND_IGNORE); fast_tpoint_collect_result fast_tp_collecting = lwp->collecting_fast_tracepoint; @@ -4351,7 +4347,7 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n) { if (debug_threads) debug_printf ("already %s LWP %ld at GDB's request\n", - (thread->last_status.kind + (thread->last_status.kind () == TARGET_WAITKIND_STOPPED) ? "stopped" : "stopping", @@ -4382,8 +4378,8 @@ linux_set_resume_request (thread_info *thread, thread_resume *resume, size_t n) struct lwp_info *rel = lwp->fork_relative; if (rel->status_pending_p - && (rel->waitstatus.kind == TARGET_WAITKIND_FORKED - || rel->waitstatus.kind == TARGET_WAITKIND_VFORKED)) + && (rel->waitstatus.kind () == TARGET_WAITKIND_FORKED + || rel->waitstatus.kind () == TARGET_WAITKIND_VFORKED)) { if (debug_threads) debug_printf ("not resuming LWP %ld: has queued stop reply\n", @@ -4771,7 +4767,7 @@ linux_process_target::resume_one_thread (thread_info *thread, /* For stop requests, we're done. */ lwp->resume = NULL; - thread->last_status.kind = TARGET_WAITKIND_IGNORE; + thread->last_status.set_ignore (); return; } @@ -4818,7 +4814,7 @@ linux_process_target::resume_one_thread (thread_info *thread, debug_printf ("leaving LWP %ld stopped\n", lwpid_of (thread)); } - thread->last_status.kind = TARGET_WAITKIND_IGNORE; + thread->last_status.set_ignore (); lwp->resume = NULL; } @@ -4918,7 +4914,7 @@ linux_process_target::proceed_one_lwp (thread_info *thread, lwp_info *except) } if (thread->last_resume_kind == resume_stop - && thread->last_status.kind != TARGET_WAITKIND_IGNORE) + && thread->last_status.kind () != TARGET_WAITKIND_IGNORE) { if (debug_threads) debug_printf (" client wants LWP to remain %ld stopped\n", |