20#include "gdbsupport/common-defs.h"
24#include <sys/sysinfo.h>
32#include <netinet/in.h>
35#include "gdbsupport/xml-utils.h"
36#include "gdbsupport/buffer.h"
39#include "gdbsupport/filestuff.h"
42#define NAMELEN(dirent) strlen ((dirent)->d_name)
55#define MAX_PID_T_STRLEN (sizeof ("-9223372036854775808") - 1)
67 sprintf (filename,
"/proc/%lld/task/%lld/stat",
70 gdb::optional<std::string> content = read_text_file_to_string (filename);
71 if (!content.has_value ())
75 std::string::size_type pos = content->find_last_of (
')');
76 if (pos == std::string::npos)
82 for (
int i = 0; i < 37; ++i)
85 pos = content->find_first_of (
' ', pos);
86 if (pos == std::string::npos)
90 pos = content->find_first_not_of (
' ', pos);
91 if (pos == std::string::npos)
95 if (sscanf (&(*content)[pos],
"%d", &core) == 0)
108 std::string stat_path = string_printf (
"/proc/%lld/stat",
pid);
109 gdb_file_up fp = gdb_fopen_cloexec (stat_path,
"r");
120 int items_read = fscanf (fp.get (),
"%lld %17s", &stat_pid, cmd);
122 if (items_read == 2 &&
pid == stat_pid)
124 cmd[strlen (cmd) - 1] =
'\0';
125 strncpy (command, cmd + 1, maxlen);
131 snprintf (command, maxlen,
"%lld",
pid);
134 command[maxlen - 1] =
'\0';
143 std::string pathname = string_printf (
"/proc/%lld/cmdline",
pid);
144 char *commandline = NULL;
145 gdb_file_up
f = gdb_fopen_cloexec (pathname,
"r");
151 while (!feof (
f.get ()))
154 size_t read_bytes = fread (buf, 1,
sizeof (buf),
f.get ());
158 commandline = (
char *)
xrealloc (commandline, len + read_bytes + 1);
159 memcpy (commandline + len, buf, read_bytes);
169 for (i = 0; i < len; ++i)
170 if (commandline[i] ==
'\0')
171 commandline[i] =
' ';
173 commandline[len] =
'\0';
179 commandline = (
char *)
xmalloc (32);
180 commandline[0] =
'[';
183 len = strlen (commandline);
185 strcat (commandline,
"]");
198 struct passwd *pwentry;
201 getpwuid_r (uid, &pwd, buf,
sizeof (buf), &pwentry);
205 strncpy (user, pwentry->pw_name, maxlen - 1);
207 user[maxlen - 1] =
'\0';
222 sprintf (procentry,
"/proc/%lld",
pid);
224 if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
226 *owner = statbuf.st_uid;
244 sprintf (taskdir,
"/proc/%lld/task",
pid);
245 dir = opendir (taskdir);
248 while ((dp = readdir (dir)) != NULL)
253 if (!isdigit (dp->d_name[0])
257 sscanf (dp->d_name,
"%lld", &tid);
261 if (core >= 0 && core < num_cores)
276static gdb::optional<size_t>
279 gdb::optional<std::string> possible
280 = read_text_file_to_string (
"/sys/devices/system/cpu/possible");
282 if (!possible.has_value ())
294 unsigned long max_id = 0;
295 for (std::string::size_type start = 0; start < possible->size ();)
297 const char *start_p = &(*possible)[start];
302 unsigned long id = strtoul (start_p, &end_p, 10);
306 max_id = std::max (max_id,
id);
308 start += end_p - start_p;
309 gdb_assert (start <= possible->
size ());
330 if (count.has_value ())
333 return sysconf (_SC_NPROCESSORS_ONLN);
340 std::string buffer =
"<osdata type=\"processes\">\n";
342 dirp = opendir (
"/proc");
348 while ((dp = readdir (dirp)) != NULL)
352 char user[UT_NAMESIZE];
356 std::string cores_str;
359 if (!isdigit (dp->d_name[0])
363 sscanf (dp->d_name,
"%lld", &
pid);
372 cores = XCNEWVEC (
int, core_array_size);
375 for (i = 0; i < core_array_size && task_count > 0; ++i)
378 string_appendf (cores_str,
"%d", i);
380 task_count -= cores[i];
390 "<column name=\"pid\">%lld</column>"
391 "<column name=\"user\">%s</column>"
392 "<column name=\"command\">%s</column>"
393 "<column name=\"cores\">%s</column>"
406 buffer +=
"</osdata>\n";
442 return this->
pid < other.
pid;
454 std::string buffer =
"<osdata type=\"process groups\">\n";
456 dirp = opendir (
"/proc");
459 std::vector<pid_pgid_entry> process_list;
462 process_list.reserve (512);
466 while ((dp = readdir (dirp)) != NULL)
470 if (!isdigit (dp->d_name[0])
474 sscanf (dp->d_name,
"%lld", &
pid);
475 pgid = getpgid (
pid);
478 process_list.emplace_back (
pid, pgid);
484 std::sort (process_list.begin (), process_list.end ());
489 PID_T pgid = entry.pgid;
490 char leader_command[32];
499 "<column name=\"pgid\">%lld</column>"
500 "<column name=\"leader command\">%s</column>"
501 "<column name=\"pid\">%lld</column>"
502 "<column name=\"command line\">%s</column>"
513 buffer +=
"</osdata>\n";
525 std::string buffer =
"<osdata type=\"threads\">\n";
527 dirp = opendir (
"/proc");
532 while ((dp = readdir (dirp)) != NULL)
535 char procentry[
sizeof (
"/proc/4294967295")];
537 if (!isdigit (dp->d_name[0])
538 ||
NAMELEN (dp) >
sizeof (
"4294967295") - 1)
541 xsnprintf (procentry,
sizeof (procentry),
"/proc/%s",
543 if (stat (procentry, &statbuf) == 0
544 && S_ISDIR (statbuf.st_mode))
551 = string_printf (
"/proc/%s/task", dp->d_name);
553 pid = atoi (dp->d_name);
556 dirp2 = opendir (pathname.c_str ());
562 while ((dp2 = readdir (dirp2)) != NULL)
567 if (!isdigit (dp2->d_name[0])
568 ||
NAMELEN (dp2) >
sizeof (
"4294967295") - 1)
571 tid = atoi (dp2->d_name);
577 "<column name=\"pid\">%lld</column>"
578 "<column name=\"command\">%s</column>"
579 "<column name=\"tid\">%lld</column>"
580 "<column name=\"core\">%d</column>"
596 buffer +=
"</osdata>\n";
607 std::string buffer =
"<osdata type=\"cpus\">\n";
609 gdb_file_up fp = gdb_fopen_cloexec (
"/proc/cpuinfo",
"r");
616 if (fgets (buf,
sizeof (buf), fp.get ()))
622 key = strtok_r (buf,
":", &saveptr);
626 value = strtok_r (NULL,
":", &saveptr);
630 while (key[i] !=
'\t' && key[i] !=
'\0')
641 if (strcmp (key,
"processor") == 0)
646 buffer +=
"</item><item>";
651 string_xml_appendf (buffer,
652 "<column name=\"%s\">%s</column>",
657 while (!feof (fp.get ()));
663 buffer +=
"</osdata>\n";
675 std::string buffer =
"<osdata type=\"files\">\n";
677 dirp = opendir (
"/proc");
682 while ((dp = readdir (dirp)) != NULL)
685 char procentry[
sizeof (
"/proc/4294967295")];
687 if (!isdigit (dp->d_name[0])
688 ||
NAMELEN (dp) >
sizeof (
"4294967295") - 1)
691 xsnprintf (procentry,
sizeof (procentry),
"/proc/%s",
693 if (stat (procentry, &statbuf) == 0
694 && S_ISDIR (statbuf.st_mode))
700 pid = atoi (dp->d_name);
704 = string_printf (
"/proc/%s/fd", dp->d_name);
705 dirp2 = opendir (pathname.c_str ());
711 while ((dp2 = readdir (dirp2)) != NULL)
716 if (!isdigit (dp2->d_name[0]))
720 = string_printf (
"%s/%s", pathname.c_str (),
722 rslt = readlink (fdname.c_str (), buf,
730 "<column name=\"pid\">%s</column>"
731 "<column name=\"command\">%s</column>"
732 "<column name=\"file descriptor\">%s</column>"
733 "<column name=\"name\">%s</column>"
738 (rslt >= 0 ? buf : dp2->d_name));
749 buffer +=
"</osdata>\n";
776 case TCP_ESTABLISHED:
777 return "ESTABLISHED";
818 const char *proc_file;
820 if (family == AF_INET)
821 proc_file = tcp ?
"/proc/net/tcp" :
"/proc/net/udp";
822 else if (family == AF_INET6)
823 proc_file = tcp ?
"/proc/net/tcp6" :
"/proc/net/udp6";
827 gdb_file_up fp = gdb_fopen_cloexec (proc_file,
"r");
834 if (fgets (buf,
sizeof (buf), fp.get ()))
837 unsigned int local_port, remote_port, state;
838 char local_address[NI_MAXHOST], remote_address[NI_MAXHOST];
842#error "local_address and remote_address buffers too small"
845 result = sscanf (buf,
846 "%*d: %32[0-9A-F]:%X %32[0-9A-F]:%X %X %*X:%*X %*X:%*X %*X %d %*d %*u %*s\n",
847 local_address, &local_port,
848 remote_address, &remote_port,
856 char user[UT_NAMESIZE];
857 char local_service[NI_MAXSERV], remote_service[NI_MAXSERV];
859 if (family == AF_INET)
861 sscanf (local_address,
"%X",
862 &locaddr.
sin.sin_addr.s_addr);
863 sscanf (remote_address,
"%X",
864 &remaddr.
sin.sin_addr.s_addr);
866 locaddr.
sin.sin_port = htons (local_port);
867 remaddr.
sin.sin_port = htons (remote_port);
869 addr_size =
sizeof (
struct sockaddr_in);
873 sscanf (local_address,
"%8X%8X%8X%8X",
874 locaddr.
sin6.sin6_addr.s6_addr32,
875 locaddr.
sin6.sin6_addr.s6_addr32 + 1,
876 locaddr.
sin6.sin6_addr.s6_addr32 + 2,
877 locaddr.
sin6.sin6_addr.s6_addr32 + 3);
878 sscanf (remote_address,
"%8X%8X%8X%8X",
879 remaddr.
sin6.sin6_addr.s6_addr32,
880 remaddr.
sin6.sin6_addr.s6_addr32 + 1,
881 remaddr.
sin6.sin6_addr.s6_addr32 + 2,
882 remaddr.
sin6.sin6_addr.s6_addr32 + 3);
884 locaddr.
sin6.sin6_port = htons (local_port);
885 remaddr.
sin6.sin6_port = htons (remote_port);
887 locaddr.
sin6.sin6_flowinfo = 0;
888 remaddr.
sin6.sin6_flowinfo = 0;
889 locaddr.
sin6.sin6_scope_id = 0;
890 remaddr.
sin6.sin6_scope_id = 0;
892 addr_size =
sizeof (
struct sockaddr_in6);
895 locaddr.
sa.sa_family = remaddr.
sa.sa_family = family;
897 result = getnameinfo (&locaddr.
sa, addr_size,
898 local_address, sizeof (local_address),
899 local_service,
sizeof (local_service),
900 NI_NUMERICHOST | NI_NUMERICSERV
901 | (tcp ? 0 : NI_DGRAM));
905 result = getnameinfo (&remaddr.
sa, addr_size,
907 sizeof (remote_address),
909 sizeof (remote_service),
910 NI_NUMERICHOST | NI_NUMERICSERV
911 | (tcp ? 0 : NI_DGRAM));
920 "<column name=\"local address\">%s</column>"
921 "<column name=\"local port\">%s</column>"
922 "<column name=\"remote address\">%s</column>"
923 "<column name=\"remote port\">%s</column>"
924 "<column name=\"state\">%s</column>"
925 "<column name=\"user\">%s</column>"
926 "<column name=\"family\">%s</column>"
927 "<column name=\"protocol\">%s</column>"
935 (family == AF_INET) ?
"INET" :
"INET6",
936 tcp ?
"STREAM" :
"DGRAM");
940 while (!feof (fp.get ()));
949 std::string buffer =
"<osdata type=\"I sockets\">\n";
956 buffer +=
"</osdata>\n";
971 time_t t = (time_t) seconds;
976 const char *time_str = ctime_r (&t, buf);
977 strncpy (time, time_str, maxlen - 1);
978 time[maxlen - 1] =
'\0';
988 struct group *grentry = getgrgid (gid);
992 strncpy (group, grentry->gr_name, maxlen - 1);
994 group[maxlen - 1] =
'\0';
1006 std::string buffer =
"<osdata type=\"shared memory\">\n";
1008 gdb_file_up fp = gdb_fopen_cloexec (
"/proc/sysvipc/shm",
"r");
1015 if (fgets (buf,
sizeof (buf), fp.get ()))
1021 int shmid,
size, nattch;
1022 TIME_T atime, dtime, ctime;
1026 items_read = sscanf (buf,
1027 "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
1028 &key, &shmid, &perms, &
size,
1031 &uid, &gid, &cuid, &cgid,
1032 &atime, &dtime, &ctime);
1034 if (items_read == 14)
1036 char user[UT_NAMESIZE], group[UT_NAMESIZE];
1037 char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1038 char ccmd[32], lcmd[32];
1039 char atime_str[32], dtime_str[32], ctime_str[32];
1056 "<column name=\"key\">%d</column>"
1057 "<column name=\"shmid\">%d</column>"
1058 "<column name=\"permissions\">%o</column>"
1059 "<column name=\"size\">%d</column>"
1060 "<column name=\"creator command\">%s</column>"
1061 "<column name=\"last op. command\">%s</column>"
1062 "<column name=\"num attached\">%d</column>"
1063 "<column name=\"user\">%s</column>"
1064 "<column name=\"group\">%s</column>"
1065 "<column name=\"creator user\">%s</column>"
1066 "<column name=\"creator group\">%s</column>"
1067 "<column name=\"last shmat() time\">%s</column>"
1068 "<column name=\"last shmdt() time\">%s</column>"
1069 "<column name=\"last shmctl() time\">%s</column>"
1088 while (!feof (fp.get ()));
1091 buffer +=
"</osdata>\n";
1102 std::string buffer =
"<osdata type=\"semaphores\">\n";
1104 gdb_file_up fp = gdb_fopen_cloexec (
"/proc/sysvipc/sem",
"r");
1111 if (fgets (buf,
sizeof (buf), fp.get ()))
1116 unsigned int perms, nsems;
1121 items_read = sscanf (buf,
1122 "%d %d %o %u %d %d %d %d %lld %lld",
1123 &key, &semid, &perms, &nsems,
1124 &uid, &gid, &cuid, &cgid,
1127 if (items_read == 10)
1129 char user[UT_NAMESIZE], group[UT_NAMESIZE];
1130 char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1131 char otime_str[32], ctime_str[32];
1144 "<column name=\"key\">%d</column>"
1145 "<column name=\"semid\">%d</column>"
1146 "<column name=\"permissions\">%o</column>"
1147 "<column name=\"num semaphores\">%u</column>"
1148 "<column name=\"user\">%s</column>"
1149 "<column name=\"group\">%s</column>"
1150 "<column name=\"creator user\">%s</column>"
1151 "<column name=\"creator group\">%s</column>"
1152 "<column name=\"last semop() time\">%s</column>"
1153 "<column name=\"last semctl() time\">%s</column>"
1168 while (!feof (fp.get ()));
1171 buffer +=
"</osdata>\n";
1182 std::string buffer =
"<osdata type=\"message queues\">\n";
1184 gdb_file_up fp = gdb_fopen_cloexec (
"/proc/sysvipc/msg",
"r");
1191 if (fgets (buf,
sizeof (buf), fp.get ()))
1197 unsigned int perms, cbytes, qnum;
1199 TIME_T stime, rtime, ctime;
1202 items_read = sscanf (buf,
1203 "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
1204 &key, &msqid, &perms, &cbytes, &qnum,
1205 &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
1206 &stime, &rtime, &ctime);
1208 if (items_read == 14)
1210 char user[UT_NAMESIZE], group[UT_NAMESIZE];
1211 char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1212 char lscmd[32], lrcmd[32];
1213 char stime_str[32], rtime_str[32], ctime_str[32];
1230 "<column name=\"key\">%d</column>"
1231 "<column name=\"msqid\">%d</column>"
1232 "<column name=\"permissions\">%o</column>"
1233 "<column name=\"num used bytes\">%u</column>"
1234 "<column name=\"num messages\">%u</column>"
1235 "<column name=\"last msgsnd() command\">%s</column>"
1236 "<column name=\"last msgrcv() command\">%s</column>"
1237 "<column name=\"user\">%s</column>"
1238 "<column name=\"group\">%s</column>"
1239 "<column name=\"creator user\">%s</column>"
1240 "<column name=\"creator group\">%s</column>"
1241 "<column name=\"last msgsnd() time\">%s</column>"
1242 "<column name=\"last msgrcv() time\">%s</column>"
1243 "<column name=\"last msgctl() time\">%s</column>"
1262 while (!feof (fp.get ()));
1265 buffer +=
"</osdata>\n";
1276 std::string buffer =
"<osdata type=\"modules\">\n";
1278 gdb_file_up fp = gdb_fopen_cloexec (
"/proc/modules",
"r");
1285 if (fgets (buf,
sizeof (buf), fp.get ()))
1287 char *
name, *dependencies, *
status, *tmp, *saveptr;
1289 unsigned long long address;
1292 name = strtok_r (buf,
" ", &saveptr);
1296 tmp = strtok_r (NULL,
" ", &saveptr);
1299 if (sscanf (tmp,
"%u", &
size) != 1)
1302 tmp = strtok_r (NULL,
" ", &saveptr);
1305 if (sscanf (tmp,
"%d", &uses) != 1)
1308 dependencies = strtok_r (NULL,
" ", &saveptr);
1309 if (dependencies == NULL)
1312 status = strtok_r (NULL,
" ", &saveptr);
1316 tmp = strtok_r (NULL,
"\n", &saveptr);
1319 if (sscanf (tmp,
"%llx", &address) != 1)
1322 string_xml_appendf (buffer,
1324 "<column name=\"name\">%s</column>"
1325 "<column name=\"size\">%u</column>"
1326 "<column name=\"num uses\">%d</column>"
1327 "<column name=\"dependencies\">%s</column>"
1328 "<column name=\"status\">%s</column>"
1329 "<column name=\"address\">%llx</column>"
1339 while (!feof (fp.get ()));
1342 buffer +=
"</osdata>\n";
1356 {
"types",
"Types",
"Listing of info os types you can list",
1358 {
"cpus",
"CPUs",
"Listing of all cpus/cores on the system",
1360 {
"files",
"File descriptors",
"Listing of all file descriptors",
1362 {
"modules",
"Kernel modules",
"Listing of all loaded kernel modules",
1364 {
"msg",
"Message queues",
"Listing of all message queues",
1366 {
"processes",
"Processes",
"Listing of all processes",
1368 {
"procgroups",
"Process groups",
"Listing of all process groups",
1370 {
"semaphores",
"Semaphores",
"Listing of all semaphores",
1372 {
"shm",
"Shared-memory regions",
"Listing of all shared-memory regions",
1374 {
"sockets",
"Sockets",
"Listing of all internet-domain sockets",
1376 {
"threads",
"Threads",
"Listing of all threads",
1378 { NULL, NULL, NULL }
1386 std::string buffer =
"<osdata type=\"types\">\n";
1390 string_xml_appendf (buffer,
1392 "<column name=\"Type\">%s</column>"
1393 "<column name=\"Description\">%s</column>"
1394 "<column name=\"Title\">%s</column>"
1400 buffer +=
"</osdata>\n";
1411 gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
1413 gdb_assert (readbuf);
1418 if (offset >= osd->
buffer.size ())
1425 len = std::min (len, osd->
buffer.size () - offset);
1426 memcpy (readbuf, &osd->
buffer[offset], len);
1434 ULONGEST offset, ULONGEST len)
1436 if (!annex || *annex ==
'\0')
1439 readbuf, offset, len);
1449 readbuf, offset, len);
void * xrealloc(void *ptr, size_t size)
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int int rusage_t pid_t pid
mach_port_t mach_port_t name mach_port_t mach_port_t name kern_return_t int status
static const char * format_socket_state(unsigned char state)
static int get_process_owner(uid_t *owner, PID_T pid)
static int get_cores_used_by_process(PID_T pid, int *cores, const int num_cores)
static LONGEST common_getter(struct osdata_type *osd, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
static std::string linux_xfer_osdata_cpus()
static gdb::optional< size_t > get_core_array_size_using_sys_possible()
static char * commandline_from_pid(PID_T pid)
static std::string linux_xfer_osdata_modules()
static void user_from_uid(char *user, int maxlen, uid_t uid)
static struct osdata_type osdata_table[]
static size_t get_core_array_size()
static std::string linux_xfer_osdata_processgroups()
static void command_from_pid(char *command, int maxlen, PID_T pid)
static void time_from_time_t(char *time, int maxlen, TIME_T seconds)
static std::string linux_xfer_osdata_sem()
LONGEST linux_common_xfer_osdata(const char *annex, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
static std::string linux_xfer_osdata_processes()
static std::string linux_xfer_osdata_threads()
static void print_sockets(unsigned short family, int tcp, std::string &buffer)
static std::string linux_xfer_osdata_msg()
int linux_common_core_of_thread(ptid_t ptid)
static void group_from_gid(char *group, int maxlen, gid_t gid)
static std::string linux_xfer_osdata_isockets()
static std::string linux_xfer_osdata_shm()
static std::string linux_xfer_osdata_fds()
static std::string linux_xfer_osdata_info_os_types()
std::string(* take_snapshot)()
pid_pgid_entry(PID_T pid_, PID_T pgid_)
bool operator<(const pid_pgid_entry &other) const