Add gdb/nat common functions for listing threads
[binutils-gdb.git] / gdb / nat / netbsd-nat.c
1 /* Internal interfaces for the NetBSD code.
2
3 Copyright (C) 2006-2020 Free Software Foundation, Inc.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 #include "gdbsupport/common-defs.h"
21 #include "nat/netbsd-nat.h"
22 #include "gdbsupport/common-debug.h"
23
24 #include <sys/types.h>
25 #include <sys/sysctl.h>
26
27 #include <cstring>
28
29 #include "gdbsupport/function-view.h"
30
31 namespace netbsd_nat
32 {
33
34 /* See netbsd-nat.h. */
35
36 const char *
37 pid_to_exec_file (pid_t pid)
38 {
39 static char buf[PATH_MAX];
40 int mib[4] = {CTL_KERN, KERN_PROC_ARGS, pid, KERN_PROC_PATHNAME};
41 size_t buflen = sizeof (buf);
42 if (::sysctl (mib, ARRAY_SIZE (mib), buf, &buflen, NULL, 0) != 0)
43 return NULL;
44 return buf;
45 }
46
47 /* Generic thread (LWP) lister within a specified PID. The CALLBACK
48 parameters is a C++ function that is called for each detected thread.
49 When the CALLBACK function returns true, the iteration is interrupted.
50
51 This function assumes internally that the queried process is stopped
52 and the number of threads does not change between two sysctl () calls. */
53
54 static bool
55 netbsd_thread_lister (const pid_t pid,
56 gdb::function_view<bool (const struct kinfo_lwp *)>
57 callback)
58 {
59 int mib[5] = {CTL_KERN, KERN_LWP, pid, sizeof (struct kinfo_lwp), 0};
60 size_t size;
61
62 if (sysctl (mib, ARRAY_SIZE (mib), NULL, &size, NULL, 0) == -1 || size == 0)
63 perror_with_name (("sysctl"));
64
65 mib[4] = size / sizeof (size_t);
66
67 gdb::unique_xmalloc_ptr<struct kinfo_lwp[]> kl
68 ((struct kinfo_lwp *) xcalloc (size, 1));
69
70 if (sysctl (mib, ARRAY_SIZE (mib), kl.get (), &size, NULL, 0) == -1
71 || size == 0)
72 perror_with_name (("sysctl"));
73
74 for (size_t i = 0; i < size / sizeof (struct kinfo_lwp); i++)
75 {
76 struct kinfo_lwp *l = &kl[i];
77
78 /* Return true if the specified thread is alive. */
79 auto lwp_alive
80 = [] (struct kinfo_lwp *lwp)
81 {
82 switch (lwp->l_stat)
83 {
84 case LSSLEEP:
85 case LSRUN:
86 case LSONPROC:
87 case LSSTOP:
88 case LSSUSPENDED:
89 return true;
90 default:
91 return false;
92 }
93 };
94
95 /* Ignore embryonic or demised threads. */
96 if (!lwp_alive (l))
97 continue;
98
99 if (callback (l))
100 return true;
101 }
102
103 return false;
104 }
105
106 /* See netbsd-nat.h. */
107
108 bool
109 thread_alive (ptid_t ptid)
110 {
111 pid_t pid = ptid.pid ();
112 lwpid_t lwp = ptid.lwp ();
113
114 auto fn
115 = [=] (const struct kinfo_lwp *kl)
116 {
117 return kl->l_lid == lwp;
118 };
119
120 return netbsd_thread_lister (pid, fn);
121 }
122
123 /* See netbsd-nat.h. */
124
125 const char *
126 thread_name (ptid_t ptid)
127 {
128 pid_t pid = ptid.pid ();
129 lwpid_t lwp = ptid.lwp ();
130
131 static char buf[KI_LNAMELEN] = {};
132
133 auto fn
134 = [=] (const struct kinfo_lwp *kl)
135 {
136 if (kl->l_lid == lwp)
137 {
138 xsnprintf (buf, sizeof buf, "%s", kl->l_name);
139 return true;
140 }
141 return false;
142 };
143
144 if (netbsd_thread_lister (pid, fn))
145 return buf;
146 else
147 return NULL;
148 }
149
150 /* See netbsd-nat.h. */
151
152 void
153 for_each_thread (pid_t pid, gdb::function_view<void (ptid_t)> callback)
154 {
155 auto fn
156 = [=, &callback] (const struct kinfo_lwp *kl)
157 {
158 ptid_t ptid = ptid_t (pid, kl->l_lid, 0);
159 callback (ptid);
160 return false;
161 };
162
163 netbsd_thread_lister (pid, fn);
164 }
165
166 }