gdb/nat/linux-procfs.c - gdb
Functions defined
Source code
- #include "common-defs.h"
- #include "linux-procfs.h"
- #include "filestuff.h"
- #include <dirent.h>
- static int
- linux_proc_get_int (pid_t lwpid, const char *field, int warn)
- {
- size_t field_len = strlen (field);
- FILE *status_file;
- char buf[100];
- int retval = -1;
- snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid);
- status_file = gdb_fopen_cloexec (buf, "r");
- if (status_file == NULL)
- {
- if (warn)
- warning (_("unable to open /proc file '%s'"), buf);
- return -1;
- }
- while (fgets (buf, sizeof (buf), status_file))
- if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':')
- {
- retval = strtol (&buf[field_len + 1], NULL, 10);
- break;
- }
- fclose (status_file);
- return retval;
- }
- int
- linux_proc_get_tgid (pid_t lwpid)
- {
- return linux_proc_get_int (lwpid, "Tgid", 1);
- }
- pid_t
- linux_proc_get_tracerpid_nowarn (pid_t lwpid)
- {
- return linux_proc_get_int (lwpid, "TracerPid", 0);
- }
- static int
- linux_proc_pid_get_state (pid_t pid, char *buffer, size_t buffer_size,
- int warn)
- {
- FILE *procfile;
- int have_state;
- xsnprintf (buffer, buffer_size, "/proc/%d/status", (int) pid);
- procfile = gdb_fopen_cloexec (buffer, "r");
- if (procfile == NULL)
- {
- if (warn)
- warning (_("unable to open /proc file '%s'"), buffer);
- return -1;
- }
- have_state = 0;
- while (fgets (buffer, buffer_size, procfile) != NULL)
- if (strncmp (buffer, "State:", 6) == 0)
- {
- have_state = 1;
- break;
- }
- fclose (procfile);
- return have_state;
- }
- int
- linux_proc_pid_is_gone (pid_t pid)
- {
- char buffer[100];
- int have_state;
- have_state = linux_proc_pid_get_state (pid, buffer, sizeof buffer, 0);
- if (have_state < 0)
- {
-
- return 1;
- }
- else if (have_state == 0)
- {
-
- return 0;
- }
- else
- {
- return (strstr (buffer, "Z (") != NULL
- || strstr (buffer, "X (") != NULL);
- }
- }
- static int
- linux_proc_pid_has_state (pid_t pid, const char *state, int warn)
- {
- char buffer[100];
- int have_state;
- have_state = linux_proc_pid_get_state (pid, buffer, sizeof buffer, warn);
- return (have_state > 0 && strstr (buffer, state) != NULL);
- }
- int
- linux_proc_pid_is_stopped (pid_t pid)
- {
- return linux_proc_pid_has_state (pid, "T (stopped)", 1);
- }
- static int
- linux_proc_pid_is_zombie_maybe_warn (pid_t pid, int warn)
- {
- return linux_proc_pid_has_state (pid, "Z (zombie)", warn);
- }
- int
- linux_proc_pid_is_zombie_nowarn (pid_t pid)
- {
- return linux_proc_pid_is_zombie_maybe_warn (pid, 0);
- }
- int
- linux_proc_pid_is_zombie (pid_t pid)
- {
- return linux_proc_pid_is_zombie_maybe_warn (pid, 1);
- }
- char *
- linux_proc_pid_get_ns (pid_t pid, const char *ns)
- {
- char buf[100];
- char nsval[64];
- int ret;
- xsnprintf (buf, sizeof (buf), "/proc/%d/ns/%s", (int) pid, ns);
- ret = readlink (buf, nsval, sizeof (nsval));
- if (0 < ret && ret < sizeof (nsval))
- {
- nsval[ret] = '\0';
- return xstrdup (nsval);
- }
- return NULL;
- }
- void
- linux_proc_attach_tgid_threads (pid_t pid,
- linux_proc_attach_lwp_func attach_lwp)
- {
- DIR *dir;
- char pathname[128];
- int new_threads_found;
- int iterations;
- if (linux_proc_get_tgid (pid) != pid)
- return;
- xsnprintf (pathname, sizeof (pathname), "/proc/%ld/task", (long) pid);
- dir = opendir (pathname);
- if (dir == NULL)
- {
- warning (_("Could not open /proc/%ld/task.\n"), (long) pid);
- return;
- }
-
- for (iterations = 0; iterations < 2; iterations++)
- {
- struct dirent *dp;
- new_threads_found = 0;
- while ((dp = readdir (dir)) != NULL)
- {
- unsigned long lwp;
-
- lwp = strtoul (dp->d_name, NULL, 10);
- if (lwp != 0)
- {
- ptid_t ptid = ptid_build (pid, lwp, 0);
- if (attach_lwp (ptid))
- new_threads_found = 1;
- }
- }
- if (new_threads_found)
- {
-
- iterations = -1;
- }
- rewinddir (dir);
- }
- closedir (dir);
- }