FreeBSD Bugzilla – Attachment 165188 Details for
Bug 201207
devel/gdb: Duplicate thread listing when attaching to running multithreaded program
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
gdb_port_ptrace_threads.patch
gdb_port_ptrace_threads.patch (text/plain), 41.93 KB, created by
John Baldwin
on 2016-01-06 23:18:19 UTC
(
hide
)
Description:
gdb_port_ptrace_threads.patch
Filename:
MIME Type:
Creator:
John Baldwin
Created:
2016-01-06 23:18:19 UTC
Size:
41.93 KB
patch
obsolete
>Index: devel/gdb/Makefile >=================================================================== >--- devel/gdb/Makefile (revision 405391) >+++ devel/gdb/Makefile (working copy) >@@ -36,18 +36,22 @@ > > ONLY_FOR_ARCHS= i386 amd64 powerpc powerpc64 # untested elsewhere, might work > >-OPTIONS_DEFINE= DEBUG EXPAT GDB_LINK GUILE KGDB PYTHON THREADS TUI >+OPTIONS_DEFINE= DEBUG EXPAT GDB_LINK GUILE KGDB PYTHON TUI > >-OPTIONS_DEFAULT= GDB_LINK KGDB THREADS TUI PORT_READLINE >+OPTIONS_DEFAULT= GDB_LINK KGDB THREAD_DB_THREAD TUI PORT_READLINE > >-OPTIONS_SINGLE= READLINE >+OPTIONS_SINGLE= READLINE THREADS > OPTIONS_SINGLE_READLINE= BASE_READLINE BUNDLED_READLINE PORT_READLINE >+OPTIONS_SINGLE_THREADS= THREAD_DB_THREAD PTRACE_THREAD NONE_THREAD > > GDB_LINK_DESC= Create ${PREFIX}/bin/gdb symlink > KGDB_DESC= Kernel Debugging Support > BASE_READLINE_DESC= from base system (experimental) > BUNDLED_READLINE_DESC= from gdb distfile >+NONE_THREAD_DESC= no thread debugging support > PORT_READLINE_DESC= from devel/readline port >+PTRACE_THREAD_DESC= use ptrace() for thread debugging (experimental) >+THREAD_DB_THREAD_DESC= use libthread_db for thread debugging > TUI_DESC= Text User Interface enabled > > OPTIONS_SUB= yes >@@ -80,14 +84,17 @@ > post-patch: > @${REINPLACE_CMD} -e 's|$$| [GDB v${PORTVERSION} for FreeBSD]|' \ > ${WRKSRC}/gdb/version.in >-.if ${PORT_OPTIONS:MTHREADS} >+.if ${PORT_OPTIONS:MTHREAD_DB_THREAD} > @${CP} ${FILESDIR}/fbsd-threads.c ${WRKSRC}/gdb/ > @${PATCH} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-threads > .endif >+.if ${PORT_OPTIONS:MTHREAD_PTRACE} >+ @${PATCH} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-threads-ptrace >+.endif > .if ${PORT_OPTIONS:MKGDB} > @${CP} -r ${FILESDIR}/kgdb/*.[ch] ${WRKSRC}/gdb/ > @${PATCH} ${PATCH_ARGS} < ${FILESDIR}/extrapatch-kgdb >-.if ${PORT_OPTIONS:MTHREADS} >+.if ${PORT_OPTIONS:MTHREAD_DB_THREAD} > @${PATCH} ${PATCH_ARGS} < \ > ${FILESDIR}/extrapatch-kgdb-configure.tgt-threads > .else >Index: devel/gdb/files/extrapatch-threads-ptrace >=================================================================== >--- devel/gdb/files/extrapatch-threads-ptrace (nonexistent) >+++ devel/gdb/files/extrapatch-threads-ptrace (working copy) >@@ -0,0 +1,1273 @@ >+diff --git bfd/elf.c bfd/elf.c >+index 9846046..6ccdb8f 100644 >+--- bfd/elf.c >++++ bfd/elf.c >+@@ -9126,6 +9126,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note) >+ case NT_SIGINFO: >+ return elfcore_make_note_pseudosection (abfd, ".note.linuxcore.siginfo", >+ note); >++ >++ case NT_FREEBSD_THRMISC: >++ if (note->namesz == 8 >++ && strcmp (note->namedata, "FreeBSD") == 0) >++ return elfcore_make_note_pseudosection (abfd, ".thrmisc", note); >++ else >++ return TRUE; >+ } >+ } >+ >+diff --git binutils/readelf.c binutils/readelf.c >+index 398a165..4aa6810 100644 >+--- binutils/readelf.c >++++ binutils/readelf.c >+@@ -15237,6 +15237,37 @@ print_v850_note (Elf_Internal_Note * pnote) >+ } >+ >+ static const char * >++get_freebsd_elfcore_note_type (unsigned e_type) >++{ >++ static char buff[64]; >++ >++ switch (e_type) >++ { >++ case NT_FREEBSD_THRMISC: >++ return _("NT_THRMISC (thrmisc structure)"); >++ case NT_FREEBSD_PROCSTAT_PROC: >++ return _("NT_PROCSTAT_PROC (proc data)"); >++ case NT_FREEBSD_PROCSTAT_FILES: >++ return _("NT_PROCSTAT_FILES (files data)"); >++ case NT_FREEBSD_PROCSTAT_VMMAP: >++ return _("NT_PROCSTAT_VMMAP (vmmap data)"); >++ case NT_FREEBSD_PROCSTAT_GROUPS: >++ return _("NT_PROCSTAT_GROUPS (groups data)"); >++ case NT_FREEBSD_PROCSTAT_UMASK: >++ return _("NT_PROCSTAT_UMASK (umask data)"); >++ case NT_FREEBSD_PROCSTAT_RLIMIT: >++ return _("NT_PROCSTAT_RLIMIT (rlimit data)"); >++ case NT_FREEBSD_PROCSTAT_OSREL: >++ return _("NT_PROCSTAT_OSREL (osreldate data)"); >++ case NT_FREEBSD_PROCSTAT_PSSTRINGS: >++ return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)"); >++ case NT_FREEBSD_PROCSTAT_AUXV: >++ return _("NT_PROCSTAT_AUXV (auxv data)"); >++ } >++ return get_note_type (e_type); >++} >++ >++static const char * >+ get_netbsd_elfcore_note_type (unsigned e_type) >+ { >+ static char buff[64]; >+@@ -15485,6 +15516,10 @@ process_note (Elf_Internal_Note * pnote) >+ /* GNU-specific object file notes. */ >+ nt = get_gnu_elf_note_type (pnote->type); >+ >++ else if (const_strneq (pnote->namedata, "FreeBSD")) >++ /* FreeBSD-specific core file notes. */ >++ nt = get_freebsd_elfcore_note_type (pnote->type); >++ >+ else if (const_strneq (pnote->namedata, "NetBSD-CORE")) >+ /* NetBSD-specific core file notes. */ >+ nt = get_netbsd_elfcore_note_type (pnote->type); >+diff --git gdb/amd64bsd-nat.c gdb/amd64bsd-nat.c >+index 66d4289..9bb34d6 100644 >+--- gdb/amd64bsd-nat.c >++++ gdb/amd64bsd-nat.c >+@@ -39,6 +39,17 @@ >+ size_t amd64bsd_xsave_len; >+ #endif >+ >++static pid_t >++get_ptrace_pid (ptid_t ptid) >++{ >++ pid_t pid; >++ >++ pid = ptid_get_lwp (ptid); >++ if (pid == 0) >++ pid = ptid_get_pid (ptid); >++ return pid; >++} >++ >+ /* Fetch register REGNUM from the inferior. If REGNUM is -1, do this >+ for all registers (including the floating-point registers). */ >+ >+@@ -52,7 +63,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, >+ { >+ struct reg regs; >+ >+- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't get registers")); >+ >+@@ -70,7 +81,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, >+ if (amd64bsd_xsave_len != 0) >+ { >+ xstateregs = alloca (amd64bsd_xsave_len); >+- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) >+ perror_with_name (_("Couldn't get extended state status")); >+ >+@@ -79,7 +90,7 @@ amd64bsd_fetch_inferior_registers (struct target_ops *ops, >+ } >+ #endif >+ >+- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't get floating point status")); >+ >+@@ -100,13 +111,13 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, >+ { >+ struct reg regs; >+ >+- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't get registers")); >+ >+ amd64_collect_native_gregset (regcache, ®s, regnum); >+ >+- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't write registers")); >+ >+@@ -123,26 +134,26 @@ amd64bsd_store_inferior_registers (struct target_ops *ops, >+ if (amd64bsd_xsave_len != 0) >+ { >+ xstateregs = alloca (amd64bsd_xsave_len); >+- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) >+ perror_with_name (_("Couldn't get extended state status")); >+ >+ amd64_collect_xsave (regcache, regnum, xstateregs, 0); >+ >+- if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xstateregs, amd64bsd_xsave_len) == -1) >+ perror_with_name (_("Couldn't write extended state status")); >+ return; >+ } >+ #endif >+ >+- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't get floating point status")); >+ >+ amd64_collect_fxsave (regcache, regnum, &fpregs); >+ >+- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't write floating point status")); >+ } >+@@ -172,7 +183,7 @@ amd64bsd_dr_get (ptid_t ptid, int regnum) >+ { >+ struct dbreg dbregs; >+ >+- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) >+ perror_with_name (_("Couldn't read debug registers")); >+ >+@@ -184,7 +195,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) >+ { >+ struct dbreg dbregs; >+ >+- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) >+ perror_with_name (_("Couldn't get debug registers")); >+ >+@@ -195,7 +206,7 @@ amd64bsd_dr_set (int regnum, unsigned long value) >+ >+ DBREG_DRX ((&dbregs), regnum) = value; >+ >+- if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) >+ perror_with_name (_("Couldn't write debug registers")); >+ } >+diff --git gdb/config.in gdb/config.in >+index 9ef53b3..0e3166b 100644 >+--- gdb/config.in >++++ gdb/config.in >+@@ -450,6 +450,9 @@ >+ /* Define to 1 if your system has struct lwp. */ >+ #undef HAVE_STRUCT_LWP >+ >++/* Define to 1 if `struct ptrace_lwpinfo' is a member of `pl_tdname'. */ >++#undef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME >++ >+ /* Define to 1 if your system has struct reg in <machine/reg.h>. */ >+ #undef HAVE_STRUCT_REG >+ >+diff --git gdb/configure gdb/configure >+index e8979f0..62f8886 100755 >+--- gdb/configure >++++ gdb/configure >+@@ -12502,6 +12502,22 @@ $as_echo "#define HAVE_PT_GETXMMREGS 1" >>confdefs.h >+ >+ fi >+ >++# See if <sys/ptrace.h> supports LWP names on FreeBSD >++# Older FreeBSD versions don't have the pl_tdname member of >++# `struct ptrace_lwpinfo'. >++ac_fn_c_check_member "$LINENO" "struct ptrace_lwpinfo" "pl_tdname" "ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" "#include <sys/ptrace.h> >++" >++if test "x$ac_cv_member_struct_ptrace_lwpinfo_pl_tdname" = x""yes; then : >++ >++cat >>confdefs.h <<_ACEOF >++#define HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME 1 >++_ACEOF >++ >++ >++fi >++ >++ >++ >+ # Detect which type of /proc is in use, such as for Solaris. >+ >+ if test "${target}" = "${host}"; then >+diff --git gdb/configure.ac gdb/configure.ac >+index a40860a..6664355 100644 >+--- gdb/configure.ac >++++ gdb/configure.ac >+@@ -1564,6 +1564,13 @@ if test $gdb_cv_have_pt_getxmmregs = yes; then >+ [Define if sys/ptrace.h defines the PT_GETXMMREGS request.]) >+ fi >+ >++# See if <sys/ptrace.h> supports LWP names on FreeBSD >++# Older FreeBSD versions don't have the pl_tdname member of >++# `struct ptrace_lwpinfo'. >++AC_CHECK_MEMBERS([struct ptrace_lwpinfo.pl_tdname], [], [], >++ [#include <sys/ptrace.h>]) >++ >++ >+ # Detect which type of /proc is in use, such as for Solaris. >+ >+ if test "${target}" = "${host}"; then >+diff --git gdb/fbsd-nat.c gdb/fbsd-nat.c >+index 9705d45..2bc31b9 100644 >+--- gdb/fbsd-nat.c >++++ gdb/fbsd-nat.c >+@@ -22,6 +22,7 @@ >+ #include "inferior.h" >+ #include "regcache.h" >+ #include "regset.h" >++#include "gdbcmd.h" >+ #include "gdbthread.h" >+ #include "gdb_wait.h" >+ #include <sys/types.h> >+@@ -204,11 +205,338 @@ fbsd_find_memory_regions (struct target_ops *self, >+ #endif >+ >+ #ifdef PT_LWPINFO >++static int debug_fbsd_lwp; >++ >+ static ptid_t (*super_wait) (struct target_ops *, >+ ptid_t, >+ struct target_waitstatus *, >+ int); >+ >++#if defined(TDP_RFPPWAIT) || defined(HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME) >++/* Fetch the external variant of the kernel's internal process >++ structure for the process PID into KP. */ >++ >++static void >++fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp) >++{ >++ size_t len; >++ int mib[4]; >++ >++ len = sizeof *kp; >++ mib[0] = CTL_KERN; >++ mib[1] = KERN_PROC; >++ mib[2] = KERN_PROC_PID; >++ mib[3] = pid; >++ if (sysctl (mib, 4, kp, &len, NULL, 0) == -1) >++ perror_with_name (("sysctl")); >++} >++#endif >++ >++/* >++ FreeBSD's first thread support was via a "reentrant" version of libc >++ (libc_r) that first shipped in 2.2.7. This library multiplexed all >++ of the threads in a process onto a single kernel thread. This >++ library is supported via the bsd-uthread target. >++ >++ FreeBSD 5.1 introduced two new threading libraries that made use of >++ multiple kernel threads. The first (libkse) scheduled M user >++ threads onto N (<= M) kernel threads (LWPs). The second (libthr) >++ bound each user thread to a dedicated kernel thread. libkse shipped >++ as the default threading library (libpthread). >++ >++ FreeBSD 5.3 added a libthread_db to abstract the interface across >++ the various thread libraries (libc_r, libkse, and libthr). >++ >++ FreeBSD 7.0 switched the default threading library from from libkse >++ to libpthread and removed libc_r. >++ >++ FreeBSD 8.0 removed libkse and the in-kernel support for it. The >++ only threading library supported by 8.0 and later is libthr which >++ ties each user thread directly to an LWP. To simplify the >++ implementation, this target only supports LWP-backed threads using >++ ptrace directly rather than libthread_db. >++*/ >++ >++/* Return true if PTID is still active in the inferior. */ >++ >++static int >++fbsd_thread_alive (struct target_ops *ops, ptid_t ptid) >++{ >++ if (ptid_lwp_p (ptid)) >++ { >++ struct ptrace_lwpinfo pl; >++ >++ if (ptrace (PT_LWPINFO, ptid_get_lwp (ptid), (caddr_t)&pl, sizeof pl) >++ == -1) >++ return 0; >++#ifdef PL_FLAG_EXITED >++ if (pl.pl_flags & PL_FLAG_EXITED) >++ return 0; >++#endif >++ } >++ >++ return 1; >++} >++ >++/* Convert PTID to a string. Returns the string in a static >++ buffer. */ >++ >++static char * >++fbsd_pid_to_str (struct target_ops *ops, ptid_t ptid) >++{ >++ lwpid_t lwp; >++ >++ lwp = ptid_get_lwp (ptid); >++ if (lwp != 0) >++ { >++ static char buf[64]; >++ int pid = ptid_get_pid (ptid); >++ >++ xsnprintf (buf, sizeof buf, "process %d, LWP %d", pid, lwp); >++ return buf; >++ } >++ >++ return normal_pid_to_str (ptid); >++} >++ >++#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME >++static char * >++fbsd_thread_name (struct target_ops *self, struct thread_info *thr) >++{ >++ struct ptrace_lwpinfo pl; >++ struct kinfo_proc kp; >++ int pid = ptid_get_pid (thr->ptid); >++ long lwp = ptid_get_lwp (thr->ptid); >++ static char buf[64]; >++ >++ fbsd_fetch_kinfo_proc (pid, &kp); >++ if (ptrace (PT_LWPINFO, lwp, (caddr_t)&pl, sizeof pl) == -1) >++ perror_with_name (("ptrace")); >++ if (strcmp (kp.ki_comm, pl.pl_tdname) == 0) >++ return NULL; >++ xsnprintf (buf, sizeof buf, "%s", pl.pl_tdname); >++ return buf; >++} >++#endif >++ >++#ifdef PT_LWP_EVENTS >++static void >++fbsd_switch_to_threaded (pid_t pid) >++{ >++ struct cleanup *cleanup; >++ lwpid_t *lwps; >++ struct ptrace_lwpinfo *pl; >++ int i, nlwps; >++ >++ nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); >++ if (nlwps == -1) >++ perror_with_name (("ptrace")); >++ >++ lwps = xcalloc (nlwps, sizeof *lwps); >++ cleanup = make_cleanup (xfree, lwps); >++ >++ nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t)lwps, nlwps); >++ if (nlwps == -1) >++ perror_with_name (("ptrace")); >++ pl = xcalloc (nlwps, sizeof *pl); >++ make_cleanup (xfree, pl); >++ for (i = 0; i < nlwps; i++) >++ { >++ if (ptrace (PT_LWPINFO, lwps[i], (caddr_t)&pl[i], sizeof pl[i]) == -1) >++ perror_with_name (("ptrace")); >++ } >++ >++ /* Choose a candidate thread for the main thread. Prefer the first >++ non-BORN and non-EXITED thread. If all threads are newborns, use >++ the first non-EXITED thread. */ >++ for (i = 0; i < nlwps; i++) >++ { >++ ptid_t ptid = ptid_build (pid, lwps[i], 0); >++ >++ if ((pl[i].pl_flags & (PL_FLAG_BORN | PL_FLAG_EXITED)) != 0) >++ continue; >++ >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: using LWP %u as main thread\n", >++ lwps[i]); >++ gdb_assert (!in_thread_list (ptid)); >++ thread_change_ptid (inferior_ptid, ptid); >++ break; >++ } >++ for (i = 0; i < nlwps; i++) >++ { >++ ptid_t ptid = ptid_build (pid, lwps[i], 0); >++ >++ if (pl[i].pl_flags & PL_FLAG_EXITED) >++ continue; >++ >++ if (!ptid_lwp_p (inferior_ptid)) >++ { >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: using LWP %u as main thread\n", >++ lwps[i]); >++ gdb_assert (!in_thread_list (ptid)); >++ thread_change_ptid (inferior_ptid, ptid); >++ } >++ else if (!in_thread_list (ptid)) >++ { >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: adding thread for LWP %u\n", >++ lwps[i]); >++ add_thread (ptid); >++ } >++ } >++ >++ do_cleanups (cleanup); >++} >++ >++static void >++fbsd_enable_lwp_events (pid_t pid) >++{ >++ if (ptrace (PT_LWP_EVENTS, pid, (PTRACE_TYPE_ARG3)0, 1) == -1) >++ perror_with_name (("ptrace")); >++} >++#else >++static void >++fbsd_add_threads (pid_t pid, int nlwps) >++{ >++ struct cleanup *cleanup; >++ lwpid_t *lwps; >++ int i; >++ >++ lwps = xcalloc (nlwps, sizeof *lwps); >++ cleanup = make_cleanup (xfree, lwps); >++ >++ nlwps = ptrace (PT_GETLWPLIST, pid, (caddr_t)lwps, nlwps); >++ if (nlwps == -1) >++ perror_with_name (("ptrace")); >++ >++ for (i = 0; i < nlwps; i++) >++ { >++ ptid_t ptid = ptid_build (pid, lwps[i], 0); >++ >++ /* If this inferior is not using LWP ptids, use the first LWP as >++ the main thread. */ >++ if (!ptid_lwp_p (inferior_ptid)) >++ { >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: using LWP %u as main thread\n", >++ lwps[i]); >++ gdb_assert (!in_thread_list (ptid)); >++ thread_change_ptid (inferior_ptid, ptid); >++ } >++ else if (!in_thread_list (ptid)) >++ { >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: adding thread for LWP %u\n", >++ lwps[i]); >++ gdb_assert (ptid_lwp_p (inferior_ptid)); >++ add_thread (ptid); >++ } >++ } >++ do_cleanups (cleanup); >++} >++#endif >++ >++/* Implement the to_update_thread_list target method for this >++ target. */ >++ >++static void >++fbsd_update_thread_list (struct target_ops *ops) >++{ >++#ifdef PT_LWP_EVENTS >++ /* With support for thread events, threads are added/deleted from the >++ list as events are reported, so just try deleting exited threads. */ >++ delete_exited_threads (); >++#else >++ int nlwps; >++ int pid = ptid_get_pid (inferior_ptid); >++ >++ prune_threads(); >++ >++ nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); >++ if (nlwps == -1) >++ perror_with_name (("ptrace")); >++ >++ /* Leave single-threaded processes with a non-threaded ptid alone. */ >++ if (nlwps == 1 && !ptid_lwp_p (inferior_ptid)) >++ return; >++ >++ fbsd_add_threads (pid, nlwps); >++#endif >++} >++ >++static void (*super_resume) (struct target_ops *, >++ ptid_t, >++ int, >++ enum gdb_signal); >++ >++static int >++resume_one_thread_cb(struct thread_info *tp, void *data) >++{ >++ ptid_t *ptid = data; >++ int request; >++ >++ if (ptid_get_pid (tp->ptid) != ptid_get_pid (*ptid)) >++ return 0; >++ >++ if (ptid_get_lwp (tp->ptid) == ptid_get_lwp (*ptid)) >++ request = PT_RESUME; >++ else >++ request = PT_SUSPEND; >++ >++ if (ptrace (request, ptid_get_lwp (tp->ptid), (caddr_t)0, 0) == -1) >++ perror_with_name (("ptrace")); >++ return 0; >++} >++ >++static int >++resume_all_threads_cb(struct thread_info *tp, void *data) >++{ >++ ptid_t *filter = data; >++ >++ if (!ptid_match (tp->ptid, *filter)) >++ return 0; >++ >++ /* Ignore single-threaded processes. */ >++ if (!ptid_lwp_p (tp->ptid)) >++ return 0; >++ >++ if (ptrace (PT_RESUME, ptid_get_lwp (tp->ptid), (caddr_t)0, 0) == -1) >++ perror_with_name (("ptrace")); >++ return 0; >++} >++ >++static void >++fbsd_resume (struct target_ops *ops, >++ ptid_t ptid, int step, enum gdb_signal signo) >++{ >++ >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: fbsd_resume for ptid (%d, %ld, %ld)\n", >++ ptid_get_pid (ptid), ptid_get_lwp (ptid), >++ ptid_get_tid (ptid)); >++ if (ptid_lwp_p (ptid)) >++ { >++ /* If ptid is a specific LWP, suspend all other LWPs in the process. */ >++ iterate_over_threads (resume_one_thread_cb, &ptid); >++ } >++ else >++ { >++ /* If ptid is a wildcard, resume all matching threads (they won't run >++ until the process is continued however). */ >++ iterate_over_threads (resume_all_threads_cb, &ptid); >++ ptid = inferior_ptid; >++ } >++ super_resume (ops, ptid, step, signo); >++} >++ >+ #ifdef TDP_RFPPWAIT >+ /* >+ To catch fork events, PT_FOLLOW_FORK is set on every traced process >+@@ -289,24 +617,6 @@ fbsd_is_child_pending (pid_t pid) >+ } >+ return 0; >+ } >+- >+-/* Fetch the external variant of the kernel's internal process >+- structure for the process PID into KP. */ >+- >+-static void >+-fbsd_fetch_kinfo_proc (pid_t pid, struct kinfo_proc *kp) >+-{ >+- size_t len; >+- int mib[4]; >+- >+- len = sizeof *kp; >+- mib[0] = CTL_KERN; >+- mib[1] = KERN_PROC; >+- mib[2] = KERN_PROC_PID; >+- mib[3] = pid; >+- if (sysctl (mib, 4, kp, &len, NULL, 0) == -1) >+- perror_with_name (("sysctl")); >+-} >+ #endif >+ >+ /* Wait for the child specified by PTID to do something. Return the >+@@ -332,6 +642,8 @@ fbsd_wait (struct target_ops *ops, >+ pid = ptid_get_pid (wptid); >+ if (ptrace (PT_LWPINFO, pid, (caddr_t)&pl, sizeof pl) == -1) >+ perror_with_name (("ptrace")); >++ if (!in_thread_list (wptid)) >++ wptid = ptid_build (pid, pl.pl_lwpid, 0); >+ >+ #ifdef TDP_RFPPWAIT >+ if (pl.pl_flags & PL_FLAG_FORKED) >+@@ -386,6 +698,52 @@ fbsd_wait (struct target_ops *ops, >+ return wptid; >+ } >+ #endif >++ >++#ifdef PT_LWP_EVENTS >++ if (pl.pl_flags & PL_FLAG_BORN) >++ { >++ if (ptid_lwp_p (inferior_ptid)) >++ { >++ ptid_t ptid = ptid_build (pid, pl.pl_lwpid, 0); >++ >++ /* If a process stops with multiple newborn threads, >++ the first thread birth event will add all of the >++ pending threads in fbsd_switch_to_threaded. >++ However, each thread will still report a newborn >++ stop. */ >++ if (!in_thread_list (ptid)) >++ { >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: adding thread for LWP %u\n", >++ pl.pl_lwpid); >++ gdb_assert(!in_thread_list (ptid)); >++ add_thread (ptid); >++ } >++ } >++ else >++ fbsd_switch_to_threaded (pid); >++ ourstatus->kind = TARGET_WAITKIND_SPURIOUS; >++ return ptid_build (pid, pl.pl_lwpid, 0); >++ } >++ if (pl.pl_flags & PL_FLAG_EXITED) >++ { >++ ptid_t ptid = ptid_build (pid, pl.pl_lwpid, 0); >++ >++ gdb_assert (in_thread_list (ptid)); >++ if (debug_fbsd_lwp) >++ fprintf_unfiltered (gdb_stdlog, >++ "FLWP: deleting thread for LWP %u\n", >++ pl.pl_lwpid); >++ if (print_thread_events) >++ printf_unfiltered (_("[%s exited]\n"), target_pid_to_str >++ (ptid)); >++ delete_thread (ptid); >++ if (ptrace (PT_CONTINUE, pid, (PTRACE_TYPE_ARG3)1, 0) == -1) >++ perror_with_name (("ptrace")); >++ continue; >++ } >++#endif >+ } >+ return wptid; >+ } >+@@ -451,13 +809,19 @@ fbsd_enable_follow_fork (pid_t pid) >+ if (ptrace (PT_FOLLOW_FORK, pid, (PTRACE_TYPE_ARG3)0, 1) == -1) >+ perror_with_name (("ptrace")); >+ } >++#endif >+ >+ /* Implement the "to_post_startup_inferior" target_ops method. */ >+ >+ static void >+ fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid) >+ { >++#ifdef TDP_RFPPWAIT >+ fbsd_enable_follow_fork (ptid_get_pid (pid)); >++#endif >++#ifdef PT_LWP_EVENTS >++ fbsd_enable_lwp_events (ptid_get_pid (pid)); >++#endif >+ } >+ >+ /* Implement the "to_post_attach" target_ops method. */ >+@@ -465,9 +829,28 @@ fbsd_post_startup_inferior (struct target_ops *self, ptid_t pid) >+ static void >+ fbsd_post_attach (struct target_ops *self, int pid) >+ { >++ int nlwps; >++ >++#ifdef TDP_RFPPWAIT >+ fbsd_enable_follow_fork (pid); >+-} >+ #endif >++#ifdef PT_LWP_EVENTS >++ fbsd_enable_lwp_events (pid); >++#endif >++ >++ /* Add threads for other LWPs when attaching to a threaded process. */ >++ nlwps = ptrace (PT_GETNUMLWPS, pid, NULL, 0); >++ if (nlwps == -1) >++ perror_with_name (("ptrace")); >++ if (nlwps > 1) >++ { >++#ifdef PT_LWP_EVENTS >++ fbsd_switch_to_threaded (pid); >++#else >++ fbsd_add_threads (pid, nlwps); >++#endif >++ } >++} >+ >+ #ifdef PL_FLAG_EXEC >+ /* If the FreeBSD kernel supports PL_FLAG_EXEC, then traced processes >+@@ -493,16 +876,25 @@ fbsd_nat_add_target (struct target_ops *t) >+ t->to_pid_to_exec_file = fbsd_pid_to_exec_file; >+ t->to_find_memory_regions = fbsd_find_memory_regions; >+ #ifdef PT_LWPINFO >++ t->to_thread_alive = fbsd_thread_alive; >++ t->to_pid_to_str = fbsd_pid_to_str; >++#ifdef HAVE_STRUCT_PTRACE_LWPINFO_PL_TDNAME >++ t->to_thread_name = fbsd_thread_name; >++#endif >++ t->to_update_thread_list = fbsd_update_thread_list; >++ t->to_has_thread_control = tc_schedlock; >++ super_resume = t->to_resume; >++ t->to_resume = fbsd_resume; >+ super_wait = t->to_wait; >+ t->to_wait = fbsd_wait; >++ t->to_post_startup_inferior = fbsd_post_startup_inferior; >++ t->to_post_attach = fbsd_post_attach; >+ #ifdef TDP_RFPPWAIT >+ t->to_follow_fork = fbsd_follow_fork; >+ t->to_insert_fork_catchpoint = fbsd_insert_fork_catchpoint; >+ t->to_remove_fork_catchpoint = fbsd_remove_fork_catchpoint; >+ t->to_insert_vfork_catchpoint = fbsd_insert_vfork_catchpoint; >+ t->to_remove_vfork_catchpoint = fbsd_remove_vfork_catchpoint; >+- t->to_post_startup_inferior = fbsd_post_startup_inferior; >+- t->to_post_attach = fbsd_post_attach; >+ #endif >+ #ifdef PL_FLAG_EXEC >+ t->to_insert_exec_catchpoint = fbsd_insert_exec_catchpoint; >+@@ -511,3 +903,21 @@ fbsd_nat_add_target (struct target_ops *t) >+ #endif >+ add_target (t); >+ } >++ >++/* Provide a prototype to silence -Wmissing-prototypes. */ >++extern initialize_file_ftype _initialize_fbsd_nat; >++ >++void >++_initialize_fbsd_nat (void) >++{ >++#ifdef PT_LWPINFO >++ add_setshow_boolean_cmd ("fbsd-lwp", class_maintenance, >++ &debug_fbsd_lwp, _("\ >++Set debugging of FreeBSD lwp module."), _("\ >++Show debugging of FreeBSD lwp module."), _("\ >++Enables printf debugging output."), >++ NULL, >++ NULL, >++ &setdebuglist, &showdebuglist); >++#endif >++} >+diff --git gdb/fbsd-tdep.c gdb/fbsd-tdep.c >+index 9609cd8..4571bad 100644 >+--- gdb/fbsd-tdep.c >++++ gdb/fbsd-tdep.c >+@@ -28,6 +28,46 @@ >+ #include "fbsd-tdep.h" >+ >+ >++/* This is how we want PTIDs from core files to be printed. */ >++ >++static char * >++fbsd_core_pid_to_str (struct gdbarch *gdbarch, ptid_t ptid) >++{ >++ static char buf[80], name[64]; >++ struct bfd_section *section; >++ bfd_size_type size; >++ char sectionstr[32]; >++ >++ if (ptid_get_lwp (ptid) != 0) >++ { >++ snprintf (sectionstr, sizeof sectionstr, ".thrmisc/%ld", >++ ptid_get_lwp (ptid)); >++ section = bfd_get_section_by_name (core_bfd, sectionstr); >++ if (section != NULL) >++ { >++ char *name; >++ >++ size = bfd_section_size (core_bfd, section); >++ name = alloca (size + 1); >++ if (bfd_get_section_contents (core_bfd, section, name, (file_ptr) 0, >++ size) && name[0] != '\0') >++ { >++ name[size] = '\0'; >++ if (strcmp(name, elf_tdata (core_bfd)->core->program) != 0) >++ { >++ snprintf (buf, sizeof buf, "LWP %ld \"%s\"", >++ ptid_get_lwp (ptid), name); >++ return buf; >++ } >++ } >++ } >++ snprintf (buf, sizeof buf, "LWP %ld", ptid_get_lwp (ptid)); >++ return buf; >++ } >++ >++ return normal_pid_to_str (ptid); >++} >++ >+ static int >+ find_signalled_thread (struct thread_info *info, void *data) >+ { >+@@ -50,12 +90,20 @@ find_stop_signal (void) >+ return GDB_SIGNAL_0; >+ } >+ >++/* Structure for passing information from >++ fbsd_collect_thread_registers via an iterator to >++ fbsd_collect_regset_section_cb. */ >++ >+ struct fbsd_collect_regset_section_cb_data >+ { >++ struct gdbarch *gdbarch; >+ const struct regcache *regcache; >+ bfd *obfd; >+ char *note_data; >+ int *note_size; >++ unsigned long lwp; >++ enum gdb_signal stop_signal; >++ int abort_iteration; >+ }; >+ >+ static void >+@@ -66,6 +114,9 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, >+ char *buf; >+ struct fbsd_collect_regset_section_cb_data *data = cb_data; >+ >++ if (data->abort_iteration) >++ return; >++ >+ gdb_assert (regset->collect_regset); >+ >+ buf = xmalloc (size); >+@@ -74,13 +125,86 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, >+ /* PRSTATUS still needs to be treated specially. */ >+ if (strcmp (sect_name, ".reg") == 0) >+ data->note_data = (char *) elfcore_write_prstatus >+- (data->obfd, data->note_data, data->note_size, >+- ptid_get_pid (inferior_ptid), find_stop_signal (), buf); >++ (data->obfd, data->note_data, data->note_size, data->lwp, >++ gdb_signal_to_host (data->stop_signal), buf); >+ else >+ data->note_data = (char *) elfcore_write_register_note >+ (data->obfd, data->note_data, data->note_size, >+ sect_name, buf, size); >+ xfree (buf); >++ >++ if (data->note_data == NULL) >++ data->abort_iteration = 1; >++} >++ >++/* Records the thread's register state for the corefile note >++ section. */ >++ >++static char * >++fbsd_collect_thread_registers (const struct regcache *regcache, >++ ptid_t ptid, bfd *obfd, >++ char *note_data, int *note_size, >++ enum gdb_signal stop_signal) >++{ >++ struct gdbarch *gdbarch = get_regcache_arch (regcache); >++ struct fbsd_collect_regset_section_cb_data data; >++ >++ data.gdbarch = gdbarch; >++ data.regcache = regcache; >++ data.obfd = obfd; >++ data.note_data = note_data; >++ data.note_size = note_size; >++ data.stop_signal = stop_signal; >++ data.abort_iteration = 0; >++ data.lwp = ptid_get_lwp (ptid); >++ >++ gdbarch_iterate_over_regset_sections (gdbarch, >++ fbsd_collect_regset_section_cb, >++ &data, regcache); >++ return data.note_data; >++} >++ >++struct fbsd_corefile_thread_data >++{ >++ struct gdbarch *gdbarch; >++ int pid; >++ bfd *obfd; >++ char *note_data; >++ int *note_size; >++ enum gdb_signal stop_signal; >++}; >++ >++/* Called by gdbthread.c once per thread. Records the thread's >++ register state for the corefile note section. */ >++ >++static int >++fbsd_corefile_thread_callback (struct thread_info *info, void *data) >++{ >++ struct fbsd_corefile_thread_data *args = data; >++ >++ /* It can be current thread >++ which cannot be removed by update_thread_list. */ >++ if (info->state == THREAD_EXITED) >++ return 0; >++ >++ if (ptid_get_pid (info->ptid) == args->pid) >++ { >++ struct cleanup *old_chain; >++ struct regcache *regcache; >++ >++ regcache = get_thread_arch_regcache (info->ptid, args->gdbarch); >++ >++ old_chain = save_inferior_ptid (); >++ inferior_ptid = info->ptid; >++ target_fetch_registers (regcache, -1); >++ do_cleanups (old_chain); >++ >++ args->note_data = fbsd_collect_thread_registers >++ (regcache, info->ptid, args->obfd, args->note_data, >++ args->note_size, args->stop_signal); >++ } >++ >++ return !args->note_data; >+ } >+ >+ /* Create appropriate note sections for a corefile, returning them in >+@@ -89,10 +213,9 @@ fbsd_collect_regset_section_cb (const char *sect_name, int size, >+ static char * >+ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) >+ { >+- struct regcache *regcache = get_current_regcache (); >+- char *note_data; >++ struct fbsd_corefile_thread_data thread_args; >++ char *note_data = NULL; >+ Elf_Internal_Ehdr *i_ehdrp; >+- struct fbsd_collect_regset_section_cb_data data; >+ >+ /* Put a "FreeBSD" label in the ELF header. */ >+ i_ehdrp = elf_elfheader (obfd); >+@@ -100,16 +223,6 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) >+ >+ gdb_assert (gdbarch_iterate_over_regset_sections_p (gdbarch)); >+ >+- data.regcache = regcache; >+- data.obfd = obfd; >+- data.note_data = NULL; >+- data.note_size = note_size; >+- target_fetch_registers (regcache, -1); >+- gdbarch_iterate_over_regset_sections (gdbarch, >+- fbsd_collect_regset_section_cb, >+- &data, regcache); >+- note_data = data.note_data; >+- >+ if (get_exec_file (0)) >+ { >+ const char *fname = lbasename (get_exec_file (0)); >+@@ -123,6 +236,26 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) >+ fname, psargs); >+ } >+ >++ /* Thread register information. */ >++ TRY >++ { >++ update_thread_list (); >++ } >++ CATCH (e, RETURN_MASK_ERROR) >++ { >++ exception_print (gdb_stderr, e); >++ } >++ END_CATCH >++ >++ thread_args.gdbarch = gdbarch; >++ thread_args.pid = ptid_get_pid (inferior_ptid); >++ thread_args.obfd = obfd; >++ thread_args.note_data = note_data; >++ thread_args.note_size = note_size; >++ thread_args.stop_signal = find_stop_signal (); >++ iterate_over_threads (fbsd_corefile_thread_callback, &thread_args); >++ note_data = thread_args.note_data; >++ >+ return note_data; >+ } >+ >+@@ -131,5 +264,6 @@ fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size) >+ void >+ fbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) >+ { >++ set_gdbarch_core_pid_to_str (gdbarch, fbsd_core_pid_to_str); >+ set_gdbarch_make_corefile_notes (gdbarch, fbsd_make_corefile_notes); >+ } >+diff --git gdb/i386bsd-nat.c gdb/i386bsd-nat.c >+index ac8a19b..90426fe 100644 >+--- gdb/i386bsd-nat.c >++++ gdb/i386bsd-nat.c >+@@ -87,6 +87,17 @@ size_t i386bsd_xsave_len; >+ #endif >+ >+ >++static pid_t >++get_ptrace_pid (ptid_t ptid) >++{ >++ pid_t pid; >++ >++ pid = ptid_get_lwp (ptid); >++ if (pid == 0) >++ pid = ptid_get_pid (ptid); >++ return pid; >++} >++ >+ /* Supply the general-purpose registers in GREGS, to REGCACHE. */ >+ >+ static void >+@@ -138,7 +149,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, >+ { >+ struct reg regs; >+ >+- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't get registers")); >+ >+@@ -160,7 +171,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, >+ char *xstateregs; >+ >+ xstateregs = alloca (i386bsd_xsave_len); >+- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) >+ perror_with_name (_("Couldn't get extended state status")); >+ >+@@ -171,7 +182,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, >+ >+ #ifdef HAVE_PT_GETXMMREGS >+ if (have_ptrace_xmmregs != 0 >+- && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), >++ && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) >+ { >+ have_ptrace_xmmregs = 1; >+@@ -181,7 +192,7 @@ i386bsd_fetch_inferior_registers (struct target_ops *ops, >+ { >+ have_ptrace_xmmregs = 0; >+ #endif >+- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't get floating point status")); >+ >+@@ -203,13 +214,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, >+ { >+ struct reg regs; >+ >+- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't get registers")); >+ >+ i386bsd_collect_gregset (regcache, ®s, regnum); >+ >+- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't write registers")); >+ >+@@ -230,13 +241,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, >+ char *xstateregs; >+ >+ xstateregs = alloca (i386bsd_xsave_len); >+- if (ptrace (PT_GETXSTATE, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETXSTATE, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xstateregs, 0) == -1) >+ perror_with_name (_("Couldn't get extended state status")); >+ >+ i387_collect_xsave (regcache, -1, xstateregs, 0); >+ >+- if (ptrace (PT_SETXSTATE, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETXSTATE, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xstateregs, i386bsd_xsave_len) == -1) >+ perror_with_name (_("Couldn't write extended state status")); >+ return; >+@@ -245,14 +256,14 @@ i386bsd_store_inferior_registers (struct target_ops *ops, >+ >+ #ifdef HAVE_PT_GETXMMREGS >+ if (have_ptrace_xmmregs != 0 >+- && ptrace(PT_GETXMMREGS, ptid_get_pid (inferior_ptid), >++ && ptrace(PT_GETXMMREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xmmregs, 0) == 0) >+ { >+ have_ptrace_xmmregs = 1; >+ >+ i387_collect_fxsave (regcache, regnum, xmmregs); >+ >+- if (ptrace (PT_SETXMMREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETXMMREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) xmmregs, 0) == -1) >+ perror_with_name (_("Couldn't write XMM registers")); >+ } >+@@ -260,13 +271,13 @@ i386bsd_store_inferior_registers (struct target_ops *ops, >+ { >+ have_ptrace_xmmregs = 0; >+ #endif >+- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't get floating point status")); >+ >+ i387_collect_fsave (regcache, regnum, &fpregs); >+ >+- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't write floating point status")); >+ #ifdef HAVE_PT_GETXMMREGS >+@@ -305,7 +316,7 @@ i386bsd_dr_get (ptid_t ptid, int regnum) >+ { >+ struct dbreg dbregs; >+ >+- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) >+ perror_with_name (_("Couldn't read debug registers")); >+ >+@@ -317,7 +328,7 @@ i386bsd_dr_set (int regnum, unsigned int value) >+ { >+ struct dbreg dbregs; >+ >+- if (ptrace (PT_GETDBREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETDBREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) >+ perror_with_name (_("Couldn't get debug registers")); >+ >+@@ -328,7 +339,7 @@ i386bsd_dr_set (int regnum, unsigned int value) >+ >+ DBREG_DRX ((&dbregs), regnum) = value; >+ >+- if (ptrace (PT_SETDBREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETDBREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &dbregs, 0) == -1) >+ perror_with_name (_("Couldn't write debug registers")); >+ } >+diff --git gdb/ppcfbsd-nat.c gdb/ppcfbsd-nat.c >+index 778e19a..75654af 100644 >+--- gdb/ppcfbsd-nat.c >++++ gdb/ppcfbsd-nat.c >+@@ -37,6 +37,17 @@ >+ #include "inf-ptrace.h" >+ #include "bsd-kvm.h" >+ >++static pid_t >++get_ptrace_pid (ptid_t ptid) >++{ >++ pid_t pid; >++ >++ pid = ptid_get_lwp (ptid); >++ if (pid == 0) >++ pid = ptid_get_pid (ptid); >++ return pid; >++} >++ >+ /* Fill GDB's register array with the general-purpose register values >+ in *GREGSETP. */ >+ >+@@ -121,7 +132,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, >+ { >+ gdb_gregset_t regs; >+ >+- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't get registers")); >+ >+@@ -132,7 +143,7 @@ ppcfbsd_fetch_inferior_registers (struct target_ops *ops, >+ const struct regset *fpregset = ppc_fbsd_fpregset (); >+ gdb_fpregset_t fpregs; >+ >+- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't get FP registers")); >+ >+@@ -149,13 +160,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, >+ { >+ gdb_gregset_t regs; >+ >+- if (ptrace (PT_GETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't get registers")); >+ >+ fill_gregset (regcache, ®s, regno); >+ >+- if (ptrace (PT_SETREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) ®s, 0) == -1) >+ perror_with_name (_("Couldn't write registers")); >+ >+@@ -163,13 +174,13 @@ ppcfbsd_store_inferior_registers (struct target_ops *ops, >+ { >+ gdb_fpregset_t fpregs; >+ >+- if (ptrace (PT_GETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_GETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't get FP registers")); >+ >+ fill_fpregset (regcache, &fpregs, regno); >+ >+- if (ptrace (PT_SETFPREGS, ptid_get_pid (inferior_ptid), >++ if (ptrace (PT_SETFPREGS, get_ptrace_pid (inferior_ptid), >+ (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) >+ perror_with_name (_("Couldn't set FP registers")); >+ } >+diff --git include/elf/common.h include/elf/common.h >+index e6d8c14..39582df 100644 >+--- include/elf/common.h >++++ include/elf/common.h >+@@ -594,6 +594,20 @@ >+ /* Note segment for SystemTap probes. */ >+ #define NT_STAPSDT 3 >+ >++/* Note segments for core files on FreeBSD systems. Note name is >++ "FreeBSD". */ >++ >++#define NT_FREEBSD_THRMISC 7 /* Thread miscellaneous info. */ >++#define NT_FREEBSD_PROCSTAT_PROC 8 /* Procstat proc data. */ >++#define NT_FREEBSD_PROCSTAT_FILES 9 /* Procstat files data. */ >++#define NT_FREEBSD_PROCSTAT_VMMAP 10 /* Procstat vmmap data. */ >++#define NT_FREEBSD_PROCSTAT_GROUPS 11 /* Procstat groups data. */ >++#define NT_FREEBSD_PROCSTAT_UMASK 12 /* Procstat umask data. */ >++#define NT_FREEBSD_PROCSTAT_RLIMIT 13 /* Procstat rlimit data. */ >++#define NT_FREEBSD_PROCSTAT_OSREL 14 /* Procstat osreldate data. */ >++#define NT_FREEBSD_PROCSTAT_PSSTRINGS 15 /* Procstat ps_strings data. */ >++#define NT_FREEBSD_PROCSTAT_AUXV 16 /* Procstat auxv data. */ >++ >+ /* Note segments for core files on NetBSD systems. Note name >+ must start with "NetBSD-CORE". */ >+ > >Property changes on: devel/gdb/files/extrapatch-threads-ptrace >___________________________________________________________________ >Added: fbsd:nokeywords >## -0,0 +1 ## >+yes >\ No newline at end of property >Added: svn:eol-style >## -0,0 +1 ## >+native >\ No newline at end of property >Added: svn:mime-type >## -0,0 +1 ## >+text/plain >\ No newline at end of property
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 201207
:
158169
|
163019
|
165188
|
165447
|
165834
|
165924
|
165926
|
166037