diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/nat/netbsd-nat.c | 125 | ||||
-rw-r--r-- | gdb/nat/netbsd-nat.h | 20 |
3 files changed, 156 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 2b8a0ac..21f30e4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,16 @@ 2020-09-10 Kamil Rytarowski <n54@gmx.com> + * netbsd-nat.h: Include "gdbsupport/function-view.h". + * (netbsd_nat::thread_alive, netbsd_nat::thread_name) + (netbsd_nat::for_each_thread): Add. + * netbsd-nat.c: Include "gdbsupport/common-defs.h" and + "gdbsupport/common-debug.h". + * (netbsd_nat::netbsd_thread_lister) + (netbsd_nat::thread_alive, netbsd_nat::thread_name) + (netbsd_nat::for_each_thread): Add. + +2020-09-10 Kamil Rytarowski <n54@gmx.com> + * netbsd-nat.h: Include <unistd.h>. * (netbsd_nat::pid_to_exec_file): Add. * netbsd-nat.c: Include <sys/types.h> and <sys/sysctl.h>. diff --git a/gdb/nat/netbsd-nat.c b/gdb/nat/netbsd-nat.c index a63ac04..3f8b8b8 100644 --- a/gdb/nat/netbsd-nat.c +++ b/gdb/nat/netbsd-nat.c @@ -17,11 +17,17 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "gdbsupport/common-defs.h" #include "nat/netbsd-nat.h" +#include "gdbsupport/common-debug.h" #include <sys/types.h> #include <sys/sysctl.h> +#include <cstring> + +#include "gdbsupport/function-view.h" + namespace netbsd_nat { @@ -38,4 +44,123 @@ pid_to_exec_file (pid_t pid) return buf; } +/* Generic thread (LWP) 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. */ + +static bool +netbsd_thread_lister (const pid_t pid, + gdb::function_view<bool (const struct kinfo_lwp *)> + callback) +{ + int mib[5] = {CTL_KERN, KERN_LWP, pid, sizeof (struct kinfo_lwp), 0}; + size_t size; + + if (sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0) + perror_with_name (("sysctl")); + + mib[4] = size / sizeof (size_t); + + gdb::unique_xmalloc_ptr<struct kinfo_lwp[]> kl + ((struct kinfo_lwp *) xcalloc (size, 1)); + + if (sysctl (mib, ARRAY_SIZE (mib), kl.get (), &size, NULL, 0) == -1 + || size == 0) + perror_with_name (("sysctl")); + + for (size_t i = 0; i < size / sizeof (struct kinfo_lwp); i++) + { + struct kinfo_lwp *l = &kl[i]; + + /* Return true if the specified thread is alive. */ + auto lwp_alive + = [] (struct kinfo_lwp *lwp) + { + switch (lwp->l_stat) + { + case LSSLEEP: + case LSRUN: + case LSONPROC: + case LSSTOP: + case LSSUSPENDED: + return true; + default: + return false; + } + }; + + /* Ignore embryonic or demised threads. */ + if (!lwp_alive (l)) + continue; + + if (callback (l)) + return true; + } + + return false; +} + +/* See netbsd-nat.h. */ + +bool +thread_alive (ptid_t ptid) +{ + pid_t pid = ptid.pid (); + lwpid_t lwp = ptid.lwp (); + + auto fn + = [=] (const struct kinfo_lwp *kl) + { + return kl->l_lid == lwp; + }; + + return netbsd_thread_lister (pid, fn); +} + +/* See netbsd-nat.h. */ + +const char * +thread_name (ptid_t ptid) +{ + pid_t pid = ptid.pid (); + lwpid_t lwp = ptid.lwp (); + + static char buf[KI_LNAMELEN] = {}; + + auto fn + = [=] (const struct kinfo_lwp *kl) + { + if (kl->l_lid == lwp) + { + xsnprintf (buf, sizeof buf, "%s", kl->l_name); + return true; + } + return false; + }; + + if (netbsd_thread_lister (pid, fn)) + return buf; + else + return NULL; +} + +/* See netbsd-nat.h. */ + +void +for_each_thread (pid_t pid, gdb::function_view<void (ptid_t)> callback) +{ + auto fn + = [=, &callback] (const struct kinfo_lwp *kl) + { + ptid_t ptid = ptid_t (pid, kl->l_lid, 0); + callback (ptid); + return false; + }; + + netbsd_thread_lister (pid, fn); +} + } diff --git a/gdb/nat/netbsd-nat.h b/gdb/nat/netbsd-nat.h index d11fadd..3f2650f 100644 --- a/gdb/nat/netbsd-nat.h +++ b/gdb/nat/netbsd-nat.h @@ -20,6 +20,8 @@ #ifndef NAT_NETBSD_NAT_H #define NAT_NETBSD_NAT_H +#include "gdbsupport/function-view.h" + #include <unistd.h> namespace netbsd_nat @@ -30,6 +32,24 @@ namespace netbsd_nat extern const char *pid_to_exec_file (pid_t pid); +/* Return true if PTID is still active in the inferior. */ + +extern bool thread_alive (ptid_t ptid); + +/* Return the name assigned to a thread by an application. Returns + the string in a static buffer. + + This function assumes internally that the queried process is stopped. */ + +extern const char *thread_name (ptid_t ptid); + +/* A generic thread lister within a specific PID. The CALLBACK parameter + is a C++ function that is called for each detected thread. + + This function assumes internally that the queried process is stopped. */ + +extern void for_each_thread (pid_t pid, + gdb::function_view<void (ptid_t)> callback); } #endif |