GDB (API)
|
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 }