X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Flinux-nat.c;h=0a2bfdc57d48624936f4b85ab55f2194f3a7d75d;hb=60db1b8565060f4bd2287b060ea9724c93289982;hp=465b2acd946c9ff463c43c0783f23baa365e3c46;hpb=21987b9c060033d367abc50c29f786df4c21b10c;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 465b2acd94..0a2bfdc57d 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -1,6 +1,6 @@ /* GNU/Linux native-dependent code common to multiple platforms. - Copyright (C) 2001-2019 Free Software Foundation, Inc. + Copyright (C) 2001-2020 Free Software Foundation, Inc. This file is part of GDB. @@ -47,7 +47,7 @@ #include /* for struct stat */ #include /* for O_RDONLY */ #include "inf-loop.h" -#include "event-loop.h" +#include "gdbsupport/event-loop.h" #include "event-top.h" #include #include @@ -440,8 +440,8 @@ typedef std::unique_ptr lwp_info_up; ptid of the followed inferior. At return, inferior_ptid will be unchanged. */ -int -linux_nat_target::follow_fork (int follow_child, int detach_fork) +bool +linux_nat_target::follow_fork (bool follow_child, bool detach_fork) { if (!follow_child) { @@ -515,9 +515,12 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork) } else { - scoped_restore save_inferior_ptid - = make_scoped_restore (&inferior_ptid); - inferior_ptid = child_ptid; + /* Switching inferior_ptid is not enough, because then + inferior_thread () would crash by not finding the thread + in the current inferior. */ + scoped_restore_current_thread restore_current_thread; + thread_info *child = find_thread_ptid (this, child_ptid); + switch_to_thread (child); /* Let the thread_db layer learn about this new process. */ check_for_thread_db (); @@ -608,7 +611,7 @@ linux_nat_target::follow_fork (int follow_child, int detach_fork) check_for_thread_db (); } - return 0; + return false; } @@ -989,7 +992,7 @@ linux_nat_switch_fork (ptid_t new_ptid) /* This changes the thread's ptid while preserving the gdb thread num. Also changes the inferior pid, while preserving the inferior num. */ - thread_change_ptid (inferior_ptid, new_ptid); + thread_change_ptid (linux_target, inferior_ptid, new_ptid); /* We've just told GDB core that the thread changed target id, but, in fact, it really is a different thread, with different register @@ -1002,7 +1005,7 @@ linux_nat_switch_fork (ptid_t new_ptid) static void exit_lwp (struct lwp_info *lp) { - struct thread_info *th = find_thread_ptid (lp->ptid); + struct thread_info *th = find_thread_ptid (linux_target, lp->ptid); if (th) { @@ -1162,9 +1165,9 @@ attach_proc_task_lwp_callback (ptid_t ptid) /* Also add the LWP to gdb's thread list, in case a matching libthread_db is not found (or the process uses raw clone). */ - add_thread (lp->ptid); - set_running (lp->ptid, 1); - set_executing (lp->ptid, 1); + add_thread (linux_target, lp->ptid); + set_running (linux_target, lp->ptid, true); + set_executing (linux_target, lp->ptid, true); } return 1; @@ -1203,7 +1206,7 @@ linux_nat_target::attach (const char *args, int from_tty) ptid = ptid_t (inferior_ptid.pid (), inferior_ptid.pid (), 0); - thread_change_ptid (inferior_ptid, ptid); + thread_change_ptid (linux_target, inferior_ptid, ptid); /* Add the initial process as the first LWP to the list. */ lp = add_initial_lwp (ptid); @@ -1304,7 +1307,7 @@ get_detach_signal (struct lwp_info *lp) signo = gdb_signal_from_host (WSTOPSIG (lp->status)); else { - struct thread_info *tp = find_thread_ptid (lp->ptid); + struct thread_info *tp = find_thread_ptid (linux_target, lp->ptid); if (target_is_non_stop_p () && !tp->executing) { @@ -1315,12 +1318,13 @@ get_detach_signal (struct lwp_info *lp) } else if (!target_is_non_stop_p ()) { - struct target_waitstatus last; ptid_t last_ptid; + process_stratum_target *last_target; - get_last_target_status (&last_ptid, &last); + get_last_target_status (&last_target, &last_ptid, nullptr); - if (lp->ptid.lwp () == last_ptid.lwp ()) + if (last_target == linux_target + && lp->ptid.lwp () == last_ptid.lwp ()) signo = tp->suspend.stop_signal; } } @@ -1517,7 +1521,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lp, int step, handle the case of stepping a breakpoint instruction). */ if (step) { - struct regcache *regcache = get_thread_regcache (lp->ptid); + struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid); lp->stop_pc = regcache_read_pc (regcache); } @@ -1536,7 +1540,7 @@ linux_resume_one_lwp_throw (struct lwp_info *lp, int step, lp->stopped = 0; lp->core = -1; lp->stop_reason = TARGET_STOPPED_BY_NO_REASON; - registers_changed_ptid (lp->ptid); + registers_changed_ptid (linux_target, lp->ptid); } /* Called when we try to resume a stopped LWP and that errors out. If @@ -1595,7 +1599,7 @@ resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo) { if (lp->stopped) { - struct inferior *inf = find_inferior_ptid (lp->ptid); + struct inferior *inf = find_inferior_ptid (linux_target, lp->ptid); if (inf->vfork_child != NULL) { @@ -1649,7 +1653,7 @@ linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except) { struct thread_info *thread; - thread = find_thread_ptid (lp->ptid); + thread = find_thread_ptid (linux_target, lp->ptid); if (thread != NULL) { signo = thread->suspend.stop_signal; @@ -1696,7 +1700,8 @@ linux_nat_target::resume (ptid_t ptid, int step, enum gdb_signal signo) resume_many = (minus_one_ptid == ptid || ptid.is_pid ()); - /* Mark the lwps we're resuming as resumed. */ + /* Mark the lwps we're resuming as resumed and update their + last_resume_kind to resume_continue. */ iterate_over_lwps (ptid, resume_set_callback); /* See if it's the current inferior that should be handled @@ -1806,7 +1811,7 @@ linux_handle_syscall_trap (struct lwp_info *lp, int stopping) { struct target_waitstatus *ourstatus = &lp->waitstatus; struct gdbarch *gdbarch = target_thread_architecture (lp->ptid); - thread_info *thread = find_thread_ptid (lp->ptid); + thread_info *thread = find_thread_ptid (linux_target, lp->ptid); int syscall_number = (int) gdbarch_get_syscall_number (gdbarch, thread); if (stopping) @@ -1973,6 +1978,10 @@ linux_handle_extended_wait (struct lwp_info *lp, int status) inferior. */ linux_target->low_new_fork (lp, new_pid); } + else if (event == PTRACE_EVENT_CLONE) + { + linux_target->low_new_clone (lp, new_pid); + } if (event == PTRACE_EVENT_FORK && linux_fork_checkpointing_p (lp->ptid.pid ())) @@ -2026,15 +2035,15 @@ linux_handle_extended_wait (struct lwp_info *lp, int status) /* The process is not using thread_db. Add the LWP to GDB's list. */ target_post_attach (new_lp->ptid.lwp ()); - add_thread (new_lp->ptid); + add_thread (linux_target, new_lp->ptid); } /* Even if we're stopping the thread for some reason internal to this module, from the perspective of infrun and the user/frontend, this new thread is running until it next reports a stop. */ - set_running (new_lp->ptid, 1); - set_executing (new_lp->ptid, 1); + set_running (linux_target, new_lp->ptid, true); + set_executing (linux_target, new_lp->ptid, true); if (WSTOPSIG (status) != SIGSTOP) { @@ -2257,7 +2266,7 @@ wait_lwp (struct lwp_info *lp) if (lp->must_set_ptrace_flags) { - struct inferior *inf = find_inferior_pid (lp->ptid.pid ()); + inferior *inf = find_inferior_pid (linux_target, lp->ptid.pid ()); int options = linux_nat_ptrace_options (inf->attach_flag); linux_enable_event_reporting (lp->ptid.lwp (), options); @@ -2484,7 +2493,7 @@ linux_nat_target::low_status_is_event (int status) static int stop_wait_callback (struct lwp_info *lp) { - struct inferior *inf = find_inferior_ptid (lp->ptid); + inferior *inf = find_inferior_ptid (linux_target, lp->ptid); /* If this is a vfork parent, bail out, it is not going to report any SIGSTOP until the vfork is done with. */ @@ -2577,7 +2586,7 @@ status_callback (struct lwp_info *lp) if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT || lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT) { - struct regcache *regcache = get_thread_regcache (lp->ptid); + struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid); CORE_ADDR pc; int discard = 0; @@ -2698,7 +2707,7 @@ save_stop_reason (struct lwp_info *lp) if (!linux_target->low_status_is_event (lp->status)) return; - regcache = get_thread_regcache (lp->ptid); + regcache = get_thread_regcache (linux_target, lp->ptid); gdbarch = regcache->arch (); pc = regcache_read_pc (regcache); @@ -2721,7 +2730,7 @@ save_stop_reason (struct lwp_info *lp) { /* If we determine the LWP stopped for a SW breakpoint, trust it. Particularly don't check watchpoint - registers, because at least on s390, we'd find + registers, because, at least on s390, we'd find stopped-by-watchpoint as long as there's a watchpoint set. */ lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT; @@ -2925,7 +2934,7 @@ resumed_callback (struct lwp_info *lp) } /* Check if we should go on and pass this event to common code. - Return the affected lwp if we are, or NULL otherwise. */ + Return the affected lwp if we should, or NULL otherwise. */ static struct lwp_info * linux_nat_filter_event (int lwpid, int status) @@ -2960,7 +2969,7 @@ linux_nat_filter_event (int lwpid, int status) lp = add_lwp (ptid_t (lwpid, lwpid, 0)); lp->stopped = 1; lp->resumed = 1; - add_thread (lp->ptid); + add_thread (linux_target, lp->ptid); } if (WIFSTOPPED (status) && !lp) @@ -2986,7 +2995,7 @@ linux_nat_filter_event (int lwpid, int status) if (WIFSTOPPED (status) && lp->must_set_ptrace_flags) { - struct inferior *inf = find_inferior_pid (lp->ptid.pid ()); + inferior *inf = find_inferior_pid (linux_target, lp->ptid.pid ()); int options = linux_nat_ptrace_options (inf->attach_flag); linux_enable_event_reporting (lp->ptid.lwp (), options); @@ -3118,7 +3127,7 @@ linux_nat_filter_event (int lwpid, int status) /* Don't report signals that GDB isn't interested in, such as signals that are neither printed nor stopped upon. Stopping all - threads can be a bit time-consuming so if we want decent + threads can be a bit time-consuming, so if we want decent performance with heavily multi-threaded programs, especially when they're using a high frequency timer, we'd better avoid it if we can. */ @@ -3152,7 +3161,7 @@ linux_nat_filter_event (int lwpid, int status) if (!lp->step && WSTOPSIG (status) && sigismember (&pass_mask, WSTOPSIG (status)) && (WSTOPSIG (status) != SIGSTOP - || !find_thread_ptid (lp->ptid)->stop_requested) + || !find_thread_ptid (linux_target, lp->ptid)->stop_requested) && !linux_wstatus_maybe_breakpoint (status)) { linux_resume_one_lwp (lp, lp->step, signo); @@ -3271,7 +3280,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, if (inferior_ptid.is_pid ()) { /* Upgrade the main thread's ptid. */ - thread_change_ptid (inferior_ptid, + thread_change_ptid (linux_target, inferior_ptid, ptid_t (inferior_ptid.pid (), inferior_ptid.pid (), 0)); @@ -3416,7 +3425,7 @@ linux_nat_wait_1 (ptid_t ptid, struct target_waitstatus *ourstatus, if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT && !USE_SIGTRAP_SIGINFO) { - struct regcache *regcache = get_thread_regcache (lp->ptid); + struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid); struct gdbarch *gdbarch = regcache->arch (); int decr_pc = gdbarch_decr_pc_after_break (gdbarch); @@ -3517,7 +3526,7 @@ resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid) } else { - struct regcache *regcache = get_thread_regcache (lp->ptid); + struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid); struct gdbarch *gdbarch = regcache->arch (); try @@ -4208,8 +4217,7 @@ sigchld_handler (int signo) int old_errno = errno; if (debug_linux_nat) - ui_file_write_async_safe (gdb_stdlog, - "sigchld\n", sizeof ("sigchld\n") - 1); + gdb_stdlog->write_async_safe ("sigchld\n", sizeof ("sigchld\n") - 1); if (signo == SIGCHLD && linux_nat_event_pipe[0] != -1) @@ -4265,6 +4273,12 @@ linux_async_pipe (int enable) return previous; } +int +linux_nat_target::async_wait_fd () +{ + return linux_nat_event_pipe[0]; +} + /* target_async implementation. */ void @@ -4322,7 +4336,7 @@ linux_nat_stop_lwp (struct lwp_info *lwp) if (debug_linux_nat) { - if (find_thread_ptid (lwp->ptid)->stop_requested) + if (find_thread_ptid (linux_target, lwp->ptid)->stop_requested) fprintf_unfiltered (gdb_stdlog, "LNSL: already stopped/stop_requested %s\n", target_pid_to_str (lwp->ptid).c_str ()); @@ -4379,7 +4393,7 @@ linux_nat_target::thread_address_space (ptid_t ptid) pid = ptid.pid (); } - inf = find_inferior_pid (pid); + inf = find_inferior_pid (this, pid); gdb_assert (inf != NULL); return inf->aspace; } @@ -4535,8 +4549,9 @@ current_lwp_ptid (void) return inferior_ptid; } +void _initialize_linux_nat (); void -_initialize_linux_nat (void) +_initialize_linux_nat () { add_setshow_zuinteger_cmd ("lin-lwp", class_maintenance, &debug_linux_nat, _("\