Module Name: src Committed By: christos Date: Sat Jun 23 03:15:55 UTC 2018
Modified Files: src/external/gpl3/gdb/dist/gdb: inf-ptrace.c nbsd-nat.c Log Message: Fix thread debugging. To generate a diff of this commit: cvs rdiff -u -r1.17 -r1.18 src/external/gpl3/gdb/dist/gdb/inf-ptrace.c cvs rdiff -u -r1.5 -r1.6 src/external/gpl3/gdb/dist/gdb/nbsd-nat.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/gpl3/gdb/dist/gdb/inf-ptrace.c diff -u src/external/gpl3/gdb/dist/gdb/inf-ptrace.c:1.17 src/external/gpl3/gdb/dist/gdb/inf-ptrace.c:1.18 --- src/external/gpl3/gdb/dist/gdb/inf-ptrace.c:1.17 Fri Dec 1 17:19:59 2017 +++ src/external/gpl3/gdb/dist/gdb/inf-ptrace.c Fri Jun 22 23:15:55 2018 @@ -353,7 +353,7 @@ inf_ptrace_resume (struct target_ops *op all possible successor instructions), so we don't have to worry about that here. */ request = PT_STEP; -#if 0 +#if __NetBSD__ /* * On NetBSD the data field of PT_STEP contains the thread * to be stepped; all other threads are continued if this value is > 0 Index: src/external/gpl3/gdb/dist/gdb/nbsd-nat.c diff -u src/external/gpl3/gdb/dist/gdb/nbsd-nat.c:1.5 src/external/gpl3/gdb/dist/gdb/nbsd-nat.c:1.6 --- src/external/gpl3/gdb/dist/gdb/nbsd-nat.c:1.5 Sun Dec 10 00:36:25 2017 +++ src/external/gpl3/gdb/dist/gdb/nbsd-nat.c Fri Jun 22 23:15:55 2018 @@ -371,7 +371,7 @@ nbsd_add_threads (pid_t pid) int val; struct ptrace_lwpinfo pl; - gdb_assert (!in_thread_list (pid_to_ptid (pid))); +// gdb_assert (!in_thread_list (pid_to_ptid (pid))); pl.pl_lwpid = 0; while ((val = ptrace (PT_LWPINFO, pid, (void *)&pl, sizeof(pl))) != -1 && pl.pl_lwpid != 0) @@ -537,68 +537,13 @@ static void nbsd_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signo) { -#if defined(TDP_RFPPWAIT) && !defined(PTRACE_VFORK) - pid_t pid; - - /* Don't PT_CONTINUE a process which has a pending vfork done event. */ - if (ptid_equal (minus_one_ptid, ptid)) - pid = ptid_get_pid (inferior_ptid); - else - pid = ptid_get_pid (ptid); - if (nbsd_is_vfork_done_pending (pid)) - return; -#endif - if (debug_nbsd_lwp) fprintf_unfiltered (gdb_stdlog, "NLWP: nbsd_resume for ptid (%d, %ld, %ld)\n", ptid_get_pid (ptid), ptid_get_lwp (ptid), ptid_get_tid (ptid)); - if (ptid_lwp_p (ptid)) - { - /* FreeBSD: If ptid is a specific LWP, suspend all other LWPs in the - * process. - */ - /* NetBSD, this function is about resuming so we only deal with - * the thread we've been asked to work with - */ - struct thread_info *tp; - int request; - - ALL_NON_EXITED_THREADS (tp) - { - if (ptid_get_pid (tp->ptid) != ptid_get_pid (ptid)) - continue; - - if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (ptid)) - request = PT_RESUME; -#ifndef __NetBSD__ - else - request = PT_SUSPEND; -#endif - - if (ptrace (request, ptid_get_pid (tp->ptid), NULL, - ptid_get_lwp (tp->ptid)) == -1) - perror_with_name (("ptrace")); - } - } - else - { - /* If ptid is a wildcard, resume all matching threads (they won't run - until the process is continued however). */ - struct thread_info *tp; - - ALL_NON_EXITED_THREADS (tp) - { - if (!ptid_match (tp->ptid, ptid)) - continue; - - if (ptrace (PT_RESUME, ptid_get_pid (tp->ptid), NULL, - ptid_get_lwp (tp->ptid)) == -1) - perror_with_name (("ptrace")); - } - ptid = inferior_ptid; - } + if (ptid_get_pid(ptid) == -1) + ptid = inferior_ptid; super_resume (ops, ptid, step, signo); } @@ -613,203 +558,35 @@ nbsd_wait (struct target_ops *ops, { ptid_t wptid; - while (1) + wptid = super_wait (ops, ptid, ourstatus, target_options); + if (ourstatus->kind == TARGET_WAITKIND_STOPPED) { -#ifndef PTRACE_VFORK - wptid = nbsd_next_vfork_done (); - if (!ptid_equal (wptid, null_ptid)) - { - ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; - return wptid; - } -#endif - wptid = super_wait (ops, ptid, ourstatus, target_options); - if (ourstatus->kind == TARGET_WAITKIND_STOPPED) - { - struct ptrace_lwpinfo pl; - pid_t pid; - int status; - - pid = ptid_get_pid (wptid); - pl.pl_lwpid = 0; - if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1) - perror_with_name (("ptrace")); - - wptid = ptid_build (pid, pl.pl_lwpid, 0); - -#ifdef PT_LWP_EVENTS - if (pl.pl_flags & PL_FLAG_EXITED) - { - /* If GDB attaches to a multi-threaded process, exiting - threads might be skipped during nbsd_post_attach that - have not yet reported their PL_FLAG_EXITED event. - Ignore EXITED events for an unknown LWP. */ - if (in_thread_list (wptid)) - { - if (debug_nbsd_lwp) - fprintf_unfiltered (gdb_stdlog, - "NLWP: deleting thread for LWP %u\n", - pl.pl_lwpid); - if (print_thread_events) - printf_unfiltered (_("[%s exited]\n"), target_pid_to_str - (wptid)); - delete_thread (wptid); - } - if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1) - perror_with_name (("ptrace")); - continue; - } -#endif - - /* Switch to an LWP PTID on the first stop in a new process. - This is done after handling PL_FLAG_EXITED to avoid - switching to an exited LWP. It is done before checking - PL_FLAG_BORN in case the first stop reported after - attaching to an existing process is a PL_FLAG_BORN - event. */ - if (in_thread_list (pid_to_ptid (pid))) - { - if (debug_nbsd_lwp) - fprintf_unfiltered (gdb_stdlog, - "NLWP: using LWP %u for first thread\n", - pl.pl_lwpid); - thread_change_ptid (pid_to_ptid (pid), wptid); - } - -#ifdef PT_LWP_EVENTS - if (pl.pl_flags & PL_FLAG_BORN) - { - /* If GDB attaches to a multi-threaded process, newborn - threads might be added by nbsd_add_threads that have - not yet reported their PL_FLAG_BORN event. Ignore - BORN events for an already-known LWP. */ - if (!in_thread_list (wptid)) - { - if (debug_nbsd_lwp) - fprintf_unfiltered (gdb_stdlog, - "NLWP: adding thread for LWP %u\n", - pl.pl_lwpid); - add_thread (wptid); - } - ourstatus->kind = TARGET_WAITKIND_SPURIOUS; - return wptid; - } -#endif - -#ifdef TDP_RFPPWAIT - if (pl.pl_flags & PL_FLAG_FORKED) - { -#ifndef PTRACE_VFORK - struct kinfo_proc kp; -#endif - ptid_t child_ptid; - pid_t child; + struct ptrace_lwpinfo pl; + pid_t pid; + int status; + pid = ptid_get_pid (wptid); + // Find the lwp that caused the wait status change + pl.pl_lwpid = 0; + do { + if (ptrace (PT_LWPINFO, pid, (caddr_t) &pl, sizeof pl) == -1) + perror_with_name (("ptrace")); + if (pl.pl_event == PL_EVENT_SIGNAL) + break; + } while (pl.pl_lwpid != 0); + if (pl.pl_lwpid != 0) + wptid = ptid_build (pid, pl.pl_lwpid, 0); + if (!in_thread_list (wptid)) + add_thread (wptid); + + if (debug_nbsd_lwp) + fprintf_unfiltered (gdb_stdlog, + "NLWP: nbsd_wait returned (%d, %ld, %ld)\n", + ptid_get_pid (wptid), ptid_get_lwp (wptid), + ptid_get_tid (wptid)); + inferior_ptid = wptid; - child = pl.pl_child_pid; - ourstatus->kind = TARGET_WAITKIND_FORKED; -#ifdef PTRACE_VFORK - if (pl.pl_flags & PL_FLAG_VFORKED) - ourstatus->kind = TARGET_WAITKIND_VFORKED; -#endif - - /* Make sure the other end of the fork is stopped too. */ - child_ptid = nbsd_is_child_pending (child); - if (ptid_equal (child_ptid, null_ptid)) - { - pid = waitpid (child, &status, 0); - if (pid == -1) - perror_with_name (("waitpid")); - - gdb_assert (pid == child); - pl.pl_lwpid = 0; - if (ptrace (PT_LWPINFO, child, (caddr_t)&pl, sizeof pl) == -1) - perror_with_name (("ptrace")); - - gdb_assert (pl.pl_flags & PL_FLAG_CHILD); - child_ptid = ptid_build (child, pl.pl_lwpid, 0); - } - - /* Enable additional events on the child process. */ - nbsd_enable_proc_events (ptid_get_pid (child_ptid)); - -#ifndef PTRACE_VFORK - /* For vfork, the child process will have the P_PPWAIT - flag set. */ - nbsd_fetch_kinfo_proc (child, &kp); - if (kp.ki_flag & P_PPWAIT) - ourstatus->kind = TARGET_WAITKIND_VFORKED; -#endif - ourstatus->value.related_pid = child_ptid; - - return wptid; - } - - if (pl.pl_flags & PL_FLAG_CHILD) - { - /* Remember that this child forked, but do not report it - until the parent reports its corresponding fork - event. */ - nbsd_remember_child (wptid); - continue; - } - -#ifdef PTRACE_VFORK - if (pl.pl_flags & PL_FLAG_VFORK_DONE) - { - ourstatus->kind = TARGET_WAITKIND_VFORK_DONE; - return wptid; - } -#endif -#endif - -#ifdef PL_FLAG_EXEC - if (pl.pl_flags & PL_FLAG_EXEC) - { - ourstatus->kind = TARGET_WAITKIND_EXECD; - ourstatus->value.execd_pathname - = xstrdup (nbsd_pid_to_exec_file (NULL, pid)); - return wptid; - } -#endif - - /* Note that PL_FLAG_SCE is set for any event reported while - a thread is executing a system call in the kernel. In - particular, signals that interrupt a sleep in a system - call will report this flag as part of their event. Stops - explicitly for system call entry and exit always use - SIGTRAP, so only treat SIGTRAP events as system call - entry/exit events. */ -#ifdef PL_FLAG_SCE - if (pl.pl_flags & (PL_FLAG_SCE | PL_FLAG_SCX) - && ourstatus->value.sig == SIGTRAP) - { -#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_SYSCALL_CODE - if (catch_syscall_enabled ()) - { - if (catching_syscall_number (pl.pl_syscall_code)) - { - if (pl.pl_flags & PL_FLAG_SCE) - ourstatus->kind = TARGET_WAITKIND_SYSCALL_ENTRY; - else - ourstatus->kind = TARGET_WAITKIND_SYSCALL_RETURN; - ourstatus->value.syscall_number = pl.pl_syscall_code; - return wptid; - } - } -#endif - /* If the core isn't interested in this event, just - continue the process explicitly and wait for another - event. Note that PT_SYSCALL is "sticky" on FreeBSD - and once system call stops are enabled on a process - it stops for all system call entries and exits. */ - if (ptrace (PT_CONTINUE, pid, (caddr_t) 1, 0) == -1) - perror_with_name (("ptrace")); - continue; - } -#endif - } - return wptid; } + return wptid; } #ifdef TDP_RFPPWAIT @@ -830,35 +607,6 @@ nbsd_follow_fork (struct target_ops *ops if (ptrace (PT_DETACH, child_pid, (PTRACE_TYPE_ARG3)1, 0) == -1) perror_with_name (("ptrace")); - -#ifndef PTRACE_VFORK - if (tp->pending_follow.kind == TARGET_WAITKIND_VFORKED) - { - /* We can't insert breakpoints until the child process has - finished with the shared memory region. The parent - process doesn't wait for the child process to exit or - exec until after it has been resumed from the ptrace stop - to report the fork. Once it has been resumed it doesn't - stop again before returning to userland, so there is no - reliable way to wait on the parent. - - We can't stay attached to the child to wait for an exec - or exit because it may invoke ptrace(PT_TRACE_ME) - (e.g. if the parent process is a debugger forking a new - child process). - - In the end, the best we can do is to make sure it runs - for a little while. Hopefully it will be out of range of - any breakpoints we reinsert. Usually this is only the - single-step breakpoint at vfork's return point. */ - - usleep (10000); - - /* Schedule a fake VFORK_DONE event to report on the next - wait. */ - nbsd_add_vfork_done (inferior_ptid); - } -#endif } return 0;