Download raw body.
devel/gdb: updated p1 diff with addtional bug fix
This is a new version of gdb bug fixes. It now includes a fix for
attaching to running processes to allow ^C to interrupt and bring
the debugger back to the prompt. I also removed the ifdef guards
on PT_PTS_NAMELEN to ensure p1 is built against base with that
define.
The issue with ^C on attached processes is that gdb clears the
global inferior_ptid and installs the pass_signal handler for
SIGINT on its way to calling waitpid. When SIGINT is received
pass_signal was calling kill(0, SIGINT) which sends the signal
to the process group of gdb. However, since we attached to an
existing process in a different process group, we essentially
sent SIGINT back to gdb, causing us to be suck in a SIGINT
storm. After trying to understand how to fix this the right
way, I eventually gave up and looked at what FreeBSD does. They
have a hack for this that works for us too.
In short this diff does the following:
* Uses ptrace PT_GET_THREAD_* for both setting thread names and
detecting if threads are still alive. The thread_alive detection
fixes 'info threads' of processes whose threads exit while
debugging.
* Fixes SIGINT storm using patch from FreeBSD to direct the SIGINT
to the current inferior process instead of gdb's process group.
This allows ^C to bring us back to the gdb prompt on attached
processes.
okay?
Index: Makefile
===================================================================
RCS file: /cvs/ports/devel/gdb/Makefile,v
diff -u -p -u -r1.98 Makefile
--- Makefile 4 Dec 2025 18:28:32 -0000 1.98
+++ Makefile 12 Dec 2025 15:36:29 -0000
@@ -2,7 +2,7 @@ COMMENT= GNU debugger
CATEGORIES= devel
DISTNAME= gdb-16.3
-REVISION= 0
+REVISION= 1
HOMEPAGE= https://www.gnu.org/software/gdb/
Index: patches/patch-gdb_inflow_c
===================================================================
RCS file: patches/patch-gdb_inflow_c
diff -N patches/patch-gdb_inflow_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-gdb_inflow_c 12 Dec 2025 15:36:29 -0000
@@ -0,0 +1,17 @@
+Pass SIGINT to attached inferior
+
+Index: gdb/inflow.c
+--- gdb/inflow.c.orig
++++ gdb/inflow.c
+@@ -872,7 +872,10 @@ static void
+ pass_signal (int signo)
+ {
+ #ifndef _WIN32
+- kill (inferior_ptid.pid (), SIGINT);
++ if (inferior_ptid.pid ())
++ kill (inferior_ptid.pid (), SIGINT);
++ else
++ kill (current_inferior ()->pid, SIGINT);
+ #endif
+ }
+
Index: patches/patch-gdb_obsd-nat_c
===================================================================
RCS file: /cvs/ports/devel/gdb/patches/patch-gdb_obsd-nat_c,v
diff -u -p -u -r1.1 patch-gdb_obsd-nat_c
--- patches/patch-gdb_obsd-nat_c 4 Dec 2025 18:28:32 -0000 1.1
+++ patches/patch-gdb_obsd-nat_c 12 Dec 2025 15:36:29 -0000
@@ -1,15 +1,9 @@
-Add support for thread_name.
+Add support for thread_name and thread_alive using ptrace.
Index: gdb/obsd-nat.c
--- gdb/obsd-nat.c.orig
+++ gdb/obsd-nat.c
-@@ -23,11 +23,13 @@
-
- #include <sys/types.h>
- #include <sys/ptrace.h>
-+#include <sys/sysctl.h>
- #include "gdbsupport/gdb_wait.h"
-
+@@ -28,6 +28,7 @@
#include "inf-ptrace.h"
#include "obsd-nat.h"
#include "gdbsupport/eintr.h"
@@ -17,48 +11,129 @@ Index: gdb/obsd-nat.c
/* OpenBSD 5.2 and later include rthreads which uses a thread model
that maps userland threads directly onto kernel threads in a 1:1
-@@ -183,4 +185,69 @@ int
- obsd_nat_target::remove_fork_catchpoint (int pid)
- {
- return 0;
-+}
-+
+@@ -42,34 +43,78 @@ obsd_nat_target::pid_to_str (ptid_t ptid)
+ return normal_pid_to_str (ptid);
+ }
+
+-void
+-obsd_nat_target::update_thread_list ()
+/* Generic thread lister within a specified PID. The CALLBACK
+ parameters is a C++ function that is called for each detected thread.
+ When the CALLBACK function returns true, the iteration is interrupted.
+
-+ This function assumes internally that the queried process is stopped
-+ and the number of threads does not change between two sysctl () calls. */
++ This function assumes internally that the queried process is stopped. */
+
+static bool
+obsd_thread_lister (const pid_t pid,
-+ gdb::function_view<bool (const struct kinfo_proc *)>
++ gdb::function_view<bool (const struct ptrace_thread_state *)>
+ callback)
-+{
-+ int mib[6] = {CTL_KERN, KERN_PROC, KERN_PROC_PID | KERN_PROC_SHOW_THREADS,
-+ pid, sizeof(struct kinfo_proc), 0};
-+ size_t size;
-+
-+ if (sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0)
-+ perror_with_name (("sysctl"));
-+
-+ mib[5] = size / sizeof (struct kinfo_proc);
-+
-+ gdb::unique_xmalloc_ptr<struct kinfo_proc[]> ki
-+ ((struct kinfo_proc *) xcalloc (mib[5], sizeof (struct kinfo_proc)));
-+
-+ if (sysctl (mib, ARRAY_SIZE (mib), ki.get (), &size, NULL, 0) == -1
-+ || size == 0)
-+ perror_with_name (("sysctl"));
-+
-+ for (size_t i = 0; i < size / sizeof (struct kinfo_proc); i++)
-+ {
-+ struct kinfo_proc *l = &ki[i];
-+ if (callback (l))
+ {
+- pid_t pid = inferior_ptid.pid ();
+ struct ptrace_thread_state pts;
+
+- prune_threads ();
+-
+ if (ptrace (PT_GET_THREAD_FIRST, pid, (caddr_t)&pts, sizeof pts) == -1)
+ perror_with_name (("ptrace"));
+
+ while (pts.pts_tid != -1)
+ {
+- ptid_t ptid = ptid_t (pid, pts.pts_tid, 0);
+-
+- if (!in_thread_list (this, ptid))
+- {
+- if (inferior_ptid.lwp () == 0)
+- thread_change_ptid (this, inferior_ptid, ptid);
+- else
+- add_thread (this, ptid);
+- }
+-
++ if (callback (&pts))
+ return true;
-+ }
+ if (ptrace (PT_GET_THREAD_NEXT, pid, (caddr_t)&pts, sizeof pts) == -1)
+ perror_with_name (("ptrace"));
+ }
+
+ return false;
+ }
+
++/* Fuction to support executing callback for each alive thread */
++
++static void
++for_each_thread (pid_t pid, gdb::function_view<void (ptid_t)> callback)
++{
++ auto fn
++ = [=, &callback] (const struct ptrace_thread_state *pts)
++ {
++ ptid_t ptid = ptid_t (pid, pts->pts_tid, 0);
++ callback (ptid);
++ return false;
++ };
++
++ obsd_thread_lister (pid, fn);
++}
++
++/* Implement the "post_attach" target_ops method. */
++
++static void
++obsd_add_threads (obsd_nat_target *target, pid_t pid)
++{
++ auto fn
++ = [&target] (ptid_t ptid)
++ {
++ if (!in_thread_list (target, ptid))
++ {
++ if (inferior_ptid.lwp () == 0)
++ thread_change_ptid (target, inferior_ptid, ptid);
++ else
++ add_thread (target, ptid);
++ }
++ };
++
++ for_each_thread (pid, fn);
++}
++
++void
++obsd_nat_target::update_thread_list ()
++{
++ pid_t pid = inferior_ptid.pid ();
++
++ prune_threads ();
++ obsd_add_threads (this, pid);
++}
++
+ /* Enable additional event reporting on a new or existing process. */
+
+ static void
+@@ -143,6 +188,7 @@ void
+ obsd_nat_target::post_attach (int pid)
+ {
+ obsd_enable_proc_events (pid);
++ obsd_add_threads (this, pid);
+ }
+
+ /* Implement the virtual inf_ptrace_target::post_startup_inferior method. */
+@@ -183,4 +229,48 @@ int
+ obsd_nat_target::remove_fork_catchpoint (int pid)
+ {
+ return 0;
++}
++
++/* See obsd-nat.h. */
++
++bool
++obsd_nat_target::thread_alive (ptid_t ptid)
++{
++ pid_t pid = ptid.pid ();
++ ptid_t::lwp_type tid = ptid.lwp ();
++
++ auto fn
++ = [=] (const struct ptrace_thread_state *pts)
++ {
++ return pts->pts_tid == tid;
++ };
++
++ return obsd_thread_lister (pid, fn);
+}
+
+/* See obsd-nat.h. */
@@ -69,14 +144,14 @@ Index: gdb/obsd-nat.c
+ pid_t pid = thr->ptid.pid ();
+ ptid_t::lwp_type tid = thr->ptid.lwp ();
+
-+ static char buf[KI_MAXCOMLEN] = {};
++ static char buf[PT_PTS_NAMELEN] = {};
+
+ auto fn
-+ = [=] (const struct kinfo_proc *ki)
++ = [=] (const struct ptrace_thread_state *pts)
+ {
-+ if (ki->p_tid == tid)
++ if (pts->pts_tid == tid)
+ {
-+ xsnprintf (buf, sizeof buf, "%s", ki->p_name);
++ xsnprintf (buf, sizeof buf, "%s", pts->pts_name);
+ return true;
+ }
+ return false;
Index: patches/patch-gdb_obsd-nat_h
===================================================================
RCS file: /cvs/ports/devel/gdb/patches/patch-gdb_obsd-nat_h,v
diff -u -p -u -r1.1 patch-gdb_obsd-nat_h
--- patches/patch-gdb_obsd-nat_h 4 Dec 2025 18:28:32 -0000 1.1
+++ patches/patch-gdb_obsd-nat_h 12 Dec 2025 15:36:29 -0000
@@ -1,12 +1,13 @@
-Add support for thread_name.
+Add support for thread_name and thread_alive.
Index: gdb/obsd-nat.h
--- gdb/obsd-nat.h.orig
+++ gdb/obsd-nat.h
-@@ -27,6 +27,7 @@ class obsd_nat_target : public inf_ptrace_target
+@@ -27,6 +27,8 @@ class obsd_nat_target : public inf_ptrace_target
/* Override some methods to support threads. */
std::string pid_to_str (ptid_t) override;
void update_thread_list () override;
++ bool thread_alive (ptid_t ptid) override;
+ const char *thread_name (struct thread_info *thr) override;
ptid_t wait (ptid_t, struct target_waitstatus *, target_wait_flags) override;
devel/gdb: updated p1 diff with addtional bug fix