1 /* Linux-specific PROCFS manipulation routines.
2 Copyright (C) 2009-2015 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "common-defs.h"
20 #include "linux-procfs.h"
21 #include "filestuff.h"
24 /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not
28 linux_proc_get_int (pid_t lwpid
, const char *field
, int warn
)
30 size_t field_len
= strlen (field
);
35 snprintf (buf
, sizeof (buf
), "/proc/%d/status", (int) lwpid
);
36 status_file
= gdb_fopen_cloexec (buf
, "r");
37 if (status_file
== NULL
)
40 warning (_("unable to open /proc file '%s'"), buf
);
44 while (fgets (buf
, sizeof (buf
), status_file
))
45 if (strncmp (buf
, field
, field_len
) == 0 && buf
[field_len
] == ':')
47 retval
= strtol (&buf
[field_len
+ 1], NULL
, 10);
55 /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not
59 linux_proc_get_tgid (pid_t lwpid
)
61 return linux_proc_get_int (lwpid
, "Tgid", 1);
64 /* See linux-procfs.h. */
67 linux_proc_get_tracerpid_nowarn (pid_t lwpid
)
69 return linux_proc_get_int (lwpid
, "TracerPid", 0);
72 /* Fill in BUFFER, a buffer with BUFFER_SIZE bytes with the 'State'
73 line of /proc/PID/status. Returns -1 on failure to open the /proc
74 file, 1 if the line is found, and 0 if not found. If WARN, warn on
75 failure to open the /proc file. */
78 linux_proc_pid_get_state (pid_t pid
, char *buffer
, size_t buffer_size
,
84 xsnprintf (buffer
, buffer_size
, "/proc/%d/status", (int) pid
);
85 procfile
= gdb_fopen_cloexec (buffer
, "r");
89 warning (_("unable to open /proc file '%s'"), buffer
);
94 while (fgets (buffer
, buffer_size
, procfile
) != NULL
)
95 if (strncmp (buffer
, "State:", 6) == 0)
104 /* See linux-procfs.h declaration. */
107 linux_proc_pid_is_gone (pid_t pid
)
112 have_state
= linux_proc_pid_get_state (pid
, buffer
, sizeof buffer
, 0);
115 /* If we can't open the status file, assume the thread has
119 else if (have_state
== 0)
121 /* No "State:" line, assume thread is alive. */
126 return (strstr (buffer
, "Z (") != NULL
127 || strstr (buffer
, "X (") != NULL
);
131 /* Return non-zero if 'State' of /proc/PID/status contains STATE. If
132 WARN, warn on failure to open the /proc file. */
135 linux_proc_pid_has_state (pid_t pid
, const char *state
, int warn
)
140 have_state
= linux_proc_pid_get_state (pid
, buffer
, sizeof buffer
, warn
);
141 return (have_state
> 0 && strstr (buffer
, state
) != NULL
);
144 /* Detect `T (stopped)' in `/proc/PID/status'.
145 Other states including `T (tracing stop)' are reported as false. */
148 linux_proc_pid_is_stopped (pid_t pid
)
150 return linux_proc_pid_has_state (pid
, "T (stopped)", 1);
153 /* Return non-zero if PID is a zombie. If WARN, warn on failure to
154 open the /proc file. */
157 linux_proc_pid_is_zombie_maybe_warn (pid_t pid
, int warn
)
159 return linux_proc_pid_has_state (pid
, "Z (zombie)", warn
);
162 /* See linux-procfs.h declaration. */
165 linux_proc_pid_is_zombie_nowarn (pid_t pid
)
167 return linux_proc_pid_is_zombie_maybe_warn (pid
, 0);
170 /* See linux-procfs.h declaration. */
173 linux_proc_pid_is_zombie (pid_t pid
)
175 return linux_proc_pid_is_zombie_maybe_warn (pid
, 1);
178 /* See linux-procfs.h declaration. */
181 linux_proc_pid_get_ns (pid_t pid
, const char *ns
)
186 xsnprintf (buf
, sizeof (buf
), "/proc/%d/ns/%s", (int) pid
, ns
);
187 ret
= readlink (buf
, nsval
, sizeof (nsval
));
188 if (0 < ret
&& ret
< sizeof (nsval
))
191 return xstrdup (nsval
);
197 /* See linux-procfs.h. */
200 linux_proc_attach_tgid_threads (pid_t pid
,
201 linux_proc_attach_lwp_func attach_lwp
)
205 int new_threads_found
;
208 if (linux_proc_get_tgid (pid
) != pid
)
211 xsnprintf (pathname
, sizeof (pathname
), "/proc/%ld/task", (long) pid
);
212 dir
= opendir (pathname
);
215 warning (_("Could not open /proc/%ld/task.\n"), (long) pid
);
219 /* Scan the task list for existing threads. While we go through the
220 threads, new threads may be spawned. Cycle through the list of
221 threads until we have done two iterations without finding new
223 for (iterations
= 0; iterations
< 2; iterations
++)
227 new_threads_found
= 0;
228 while ((dp
= readdir (dir
)) != NULL
)
233 lwp
= strtoul (dp
->d_name
, NULL
, 10);
236 ptid_t ptid
= ptid_build (pid
, lwp
, 0);
238 if (attach_lwp (ptid
))
239 new_threads_found
= 1;
243 if (new_threads_found
)