1 /* Linux-specific PROCFS manipulation routines.
2 Copyright (C) 2009-2016 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"
25 /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not
29 linux_proc_get_int (pid_t lwpid
, const char *field
, int warn
)
31 size_t field_len
= strlen (field
);
36 snprintf (buf
, sizeof (buf
), "/proc/%d/status", (int) lwpid
);
37 status_file
= gdb_fopen_cloexec (buf
, "r");
38 if (status_file
== NULL
)
41 warning (_("unable to open /proc file '%s'"), buf
);
45 while (fgets (buf
, sizeof (buf
), status_file
))
46 if (strncmp (buf
, field
, field_len
) == 0 && buf
[field_len
] == ':')
48 retval
= strtol (&buf
[field_len
+ 1], NULL
, 10);
56 /* Return the TGID of LWPID from /proc/pid/status. Returns -1 if not
60 linux_proc_get_tgid (pid_t lwpid
)
62 return linux_proc_get_int (lwpid
, "Tgid", 1);
65 /* See linux-procfs.h. */
68 linux_proc_get_tracerpid_nowarn (pid_t lwpid
)
70 return linux_proc_get_int (lwpid
, "TracerPid", 0);
73 /* Fill in BUFFER, a buffer with BUFFER_SIZE bytes with the 'State'
74 line of /proc/PID/status. Returns -1 on failure to open the /proc
75 file, 1 if the line is found, and 0 if not found. If WARN, warn on
76 failure to open the /proc file. */
79 linux_proc_pid_get_state (pid_t pid
, char *buffer
, size_t buffer_size
,
85 xsnprintf (buffer
, buffer_size
, "/proc/%d/status", (int) pid
);
86 procfile
= gdb_fopen_cloexec (buffer
, "r");
90 warning (_("unable to open /proc file '%s'"), buffer
);
95 while (fgets (buffer
, buffer_size
, procfile
) != NULL
)
96 if (startswith (buffer
, "State:"))
105 /* See linux-procfs.h declaration. */
108 linux_proc_pid_is_gone (pid_t pid
)
113 have_state
= linux_proc_pid_get_state (pid
, buffer
, sizeof buffer
, 0);
116 /* If we can't open the status file, assume the thread has
120 else if (have_state
== 0)
122 /* No "State:" line, assume thread is alive. */
127 return (strstr (buffer
, "Z (") != NULL
128 || strstr (buffer
, "X (") != NULL
);
132 /* Return non-zero if 'State' of /proc/PID/status contains STATE. If
133 WARN, warn on failure to open the /proc file. */
136 linux_proc_pid_has_state (pid_t pid
, const char *state
, int warn
)
141 have_state
= linux_proc_pid_get_state (pid
, buffer
, sizeof buffer
, warn
);
142 return (have_state
> 0 && strstr (buffer
, state
) != NULL
);
145 /* Detect `T (stopped)' in `/proc/PID/status'.
146 Other states including `T (tracing stop)' are reported as false. */
149 linux_proc_pid_is_stopped (pid_t pid
)
151 return linux_proc_pid_has_state (pid
, "T (stopped)", 1);
154 /* Detect `T (tracing stop)' in `/proc/PID/status'.
155 Other states including `T (stopped)' are reported as false. */
158 linux_proc_pid_is_trace_stopped_nowarn (pid_t pid
)
160 return linux_proc_pid_has_state (pid
, "T (tracing stop)", 1);
163 /* Return non-zero if PID is a zombie. If WARN, warn on failure to
164 open the /proc file. */
167 linux_proc_pid_is_zombie_maybe_warn (pid_t pid
, int warn
)
169 return linux_proc_pid_has_state (pid
, "Z (zombie)", warn
);
172 /* See linux-procfs.h declaration. */
175 linux_proc_pid_is_zombie_nowarn (pid_t pid
)
177 return linux_proc_pid_is_zombie_maybe_warn (pid
, 0);
180 /* See linux-procfs.h declaration. */
183 linux_proc_pid_is_zombie (pid_t pid
)
185 return linux_proc_pid_is_zombie_maybe_warn (pid
, 1);
188 /* See linux-procfs.h. */
191 linux_proc_tid_get_name (ptid_t ptid
)
193 #define TASK_COMM_LEN 16 /* As defined in the kernel's sched.h. */
195 static char comm_buf
[TASK_COMM_LEN
];
198 const char *comm_val
;
199 pid_t pid
= ptid_get_pid (ptid
);
200 pid_t tid
= ptid_lwp_p (ptid
) ? ptid_get_lwp (ptid
) : ptid_get_pid (ptid
);
202 xsnprintf (comm_path
, sizeof (comm_path
),
203 "/proc/%ld/task/%ld/comm", (long) pid
, (long) tid
);
205 comm_file
= gdb_fopen_cloexec (comm_path
, "r");
206 if (comm_file
== NULL
)
209 comm_val
= fgets (comm_buf
, sizeof (comm_buf
), comm_file
);
212 if (comm_val
!= NULL
)
216 /* Make sure there is no newline at the end. */
217 for (i
= 0; i
< sizeof (comm_buf
); i
++)
219 if (comm_buf
[i
] == '\n')
230 /* See linux-procfs.h. */
233 linux_proc_attach_tgid_threads (pid_t pid
,
234 linux_proc_attach_lwp_func attach_lwp
)
238 int new_threads_found
;
241 if (linux_proc_get_tgid (pid
) != pid
)
244 xsnprintf (pathname
, sizeof (pathname
), "/proc/%ld/task", (long) pid
);
245 dir
= opendir (pathname
);
248 warning (_("Could not open /proc/%ld/task."), (long) pid
);
252 /* Scan the task list for existing threads. While we go through the
253 threads, new threads may be spawned. Cycle through the list of
254 threads until we have done two iterations without finding new
256 for (iterations
= 0; iterations
< 2; iterations
++)
260 new_threads_found
= 0;
261 while ((dp
= readdir (dir
)) != NULL
)
266 lwp
= strtoul (dp
->d_name
, NULL
, 10);
269 ptid_t ptid
= ptid_build (pid
, lwp
, 0);
271 if (attach_lwp (ptid
))
272 new_threads_found
= 1;
276 if (new_threads_found
)
288 /* See linux-procfs.h. */
291 linux_proc_task_list_dir_exists (pid_t pid
)
296 xsnprintf (pathname
, sizeof (pathname
), "/proc/%ld/task", (long) pid
);
297 return (stat (pathname
, &buf
) == 0);
300 /* See linux-procfs.h. */
303 linux_proc_pid_to_exec_file (int pid
)
305 static char buf
[PATH_MAX
];
309 xsnprintf (name
, PATH_MAX
, "/proc/%d/exe", pid
);
310 len
= readlink (name
, buf
, PATH_MAX
- 1);