GDB (API)
/home/stan/gdb/src/gdb/common/linux-procfs.c
Go to the documentation of this file.
00001 /* Linux-specific PROCFS manipulation routines.
00002    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00003 
00004    This file is part of GDB.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 3 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00018 
00019 #ifdef GDBSERVER
00020 #include "server.h"
00021 #else
00022 #include "defs.h"
00023 #include "gdb_string.h"
00024 #endif
00025 
00026 #include "linux-procfs.h"
00027 #include "filestuff.h"
00028 
00029 /* Return the TGID of LWPID from /proc/pid/status.  Returns -1 if not
00030    found.  */
00031 
00032 static int
00033 linux_proc_get_int (pid_t lwpid, const char *field)
00034 {
00035   size_t field_len = strlen (field);
00036   FILE *status_file;
00037   char buf[100];
00038   int retval = -1;
00039 
00040   snprintf (buf, sizeof (buf), "/proc/%d/status", (int) lwpid);
00041   status_file = gdb_fopen_cloexec (buf, "r");
00042   if (status_file == NULL)
00043     {
00044       warning (_("unable to open /proc file '%s'"), buf);
00045       return -1;
00046     }
00047 
00048   while (fgets (buf, sizeof (buf), status_file))
00049     if (strncmp (buf, field, field_len) == 0 && buf[field_len] == ':')
00050       {
00051         retval = strtol (&buf[field_len + 1], NULL, 10);
00052         break;
00053       }
00054 
00055   fclose (status_file);
00056   return retval;
00057 }
00058 
00059 /* Return the TGID of LWPID from /proc/pid/status.  Returns -1 if not
00060    found.  */
00061 
00062 int
00063 linux_proc_get_tgid (pid_t lwpid)
00064 {
00065   return linux_proc_get_int (lwpid, "Tgid");
00066 }
00067 
00068 /* See linux-procfs.h.  */
00069 
00070 pid_t
00071 linux_proc_get_tracerpid (pid_t lwpid)
00072 {
00073   return linux_proc_get_int (lwpid, "TracerPid");
00074 }
00075 
00076 /* Return non-zero if 'State' of /proc/PID/status contains STATE.  */
00077 
00078 static int
00079 linux_proc_pid_has_state (pid_t pid, const char *state)
00080 {
00081   char buffer[100];
00082   FILE *procfile;
00083   int retval;
00084   int have_state;
00085 
00086   xsnprintf (buffer, sizeof (buffer), "/proc/%d/status", (int) pid);
00087   procfile = gdb_fopen_cloexec (buffer, "r");
00088   if (procfile == NULL)
00089     {
00090       warning (_("unable to open /proc file '%s'"), buffer);
00091       return 0;
00092     }
00093 
00094   have_state = 0;
00095   while (fgets (buffer, sizeof (buffer), procfile) != NULL)
00096     if (strncmp (buffer, "State:", 6) == 0)
00097       {
00098         have_state = 1;
00099         break;
00100       }
00101   retval = (have_state && strstr (buffer, state) != NULL);
00102   fclose (procfile);
00103   return retval;
00104 }
00105 
00106 /* Detect `T (stopped)' in `/proc/PID/status'.
00107    Other states including `T (tracing stop)' are reported as false.  */
00108 
00109 int
00110 linux_proc_pid_is_stopped (pid_t pid)
00111 {
00112   return linux_proc_pid_has_state (pid, "T (stopped)");
00113 }
00114 
00115 /* See linux-procfs.h declaration.  */
00116 
00117 int
00118 linux_proc_pid_is_zombie (pid_t pid)
00119 {
00120   return linux_proc_pid_has_state (pid, "Z (zombie)");
00121 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines