GDBserver
linux-osdata.c
Go to the documentation of this file.
1 /* Linux-specific functions to retrieve OS data.
2 
3  Copyright (C) 2009-2018 Free Software Foundation, Inc.
4 
5  This file is part of GDB.
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 3 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 
20 #include "common-defs.h"
21 #include "linux-osdata.h"
22 
23 #include <sys/types.h>
24 #include <sys/sysinfo.h>
25 #include <ctype.h>
26 #include <utmp.h>
27 #include <time.h>
28 #include <unistd.h>
29 #include <pwd.h>
30 #include <grp.h>
31 #include <netdb.h>
32 #include <netinet/in.h>
33 #include <arpa/inet.h>
34 
35 #include "xml-utils.h"
36 #include "buffer.h"
37 #include <dirent.h>
38 #include <sys/stat.h>
39 #include "filestuff.h"
40 #include <algorithm>
41 
42 #define NAMELEN(dirent) strlen ((dirent)->d_name)
43 
44 /* Define PID_T to be a fixed size that is at least as large as pid_t,
45  so that reading pid values embedded in /proc works
46  consistently. */
47 
48 typedef long long PID_T;
49 
50 /* Define TIME_T to be at least as large as time_t, so that reading
51  time values embedded in /proc works consistently. */
52 
53 typedef long long TIME_T;
54 
55 #define MAX_PID_T_STRLEN (sizeof ("-9223372036854775808") - 1)
56 
57 /* Returns the CPU core that thread PTID is currently running on. */
58 
59 /* Compute and return the processor core of a given thread. */
60 
61 int
63 {
64  char filename[sizeof ("/proc//task//stat") + 2 * MAX_PID_T_STRLEN];
65  char *content = NULL;
66  char *p;
67  char *ts = 0;
68  int content_read = 0;
69  int i;
70  int core;
71 
72  sprintf (filename, "/proc/%lld/task/%lld/stat",
73  (PID_T) ptid_get_pid (ptid), (PID_T) ptid_get_lwp (ptid));
74  gdb_file_up f = gdb_fopen_cloexec (filename, "r");
75  if (!f)
76  return -1;
77 
78  for (;;)
79  {
80  int n;
81  content = (char *) xrealloc (content, content_read + 1024);
82  n = fread (content + content_read, 1, 1024, f.get ());
83  content_read += n;
84  if (n < 1024)
85  {
86  content[content_read] = '\0';
87  break;
88  }
89  }
90 
91  /* ps command also relies on no trailing fields ever contain ')'. */
92  p = strrchr (content, ')');
93  if (p != NULL)
94  p++;
95 
96  /* If the first field after program name has index 0, then core number is
97  the field with index 36. There's no constant for that anywhere. */
98  if (p != NULL)
99  p = strtok_r (p, " ", &ts);
100  for (i = 0; p != NULL && i != 36; ++i)
101  p = strtok_r (NULL, " ", &ts);
102 
103  if (p == NULL || sscanf (p, "%d", &core) == 0)
104  core = -1;
105 
106  xfree (content);
107 
108  return core;
109 }
110 
111 /* Finds the command-line of process PID and copies it into COMMAND.
112  At most MAXLEN characters are copied. If the command-line cannot
113  be found, PID is copied into command in text-form. */
114 
115 static void
116 command_from_pid (char *command, int maxlen, PID_T pid)
117 {
118  char *stat_path = xstrprintf ("/proc/%lld/stat", pid);
119  gdb_file_up fp = gdb_fopen_cloexec (stat_path, "r");
120 
121  command[0] = '\0';
122 
123  if (fp)
124  {
125  /* sizeof (cmd) should be greater or equal to TASK_COMM_LEN (in
126  include/linux/sched.h in the Linux kernel sources) plus two
127  (for the brackets). */
128  char cmd[18];
129  PID_T stat_pid;
130  int items_read = fscanf (fp.get (), "%lld %17s", &stat_pid, cmd);
131 
132  if (items_read == 2 && pid == stat_pid)
133  {
134  cmd[strlen (cmd) - 1] = '\0'; /* Remove trailing parenthesis. */
135  strncpy (command, cmd + 1, maxlen); /* Ignore leading parenthesis. */
136  }
137  }
138  else
139  {
140  /* Return the PID if a /proc entry for the process cannot be found. */
141  snprintf (command, maxlen, "%lld", pid);
142  }
143 
144  command[maxlen - 1] = '\0'; /* Ensure string is null-terminated. */
145 
146  xfree (stat_path);
147 }
148 
149 /* Returns the command-line of the process with the given PID. The
150  returned string needs to be freed using xfree after use. */
151 
152 static char *
154 {
155  char *pathname = xstrprintf ("/proc/%lld/cmdline", pid);
156  char *commandline = NULL;
157  gdb_file_up f = gdb_fopen_cloexec (pathname, "r");
158 
159  if (f)
160  {
161  size_t len = 0;
162 
163  while (!feof (f.get ()))
164  {
165  char buf[1024];
166  size_t read_bytes = fread (buf, 1, sizeof (buf), f.get ());
167 
168  if (read_bytes)
169  {
170  commandline = (char *) xrealloc (commandline, len + read_bytes + 1);
171  memcpy (commandline + len, buf, read_bytes);
172  len += read_bytes;
173  }
174  }
175 
176  if (commandline)
177  {
178  size_t i;
179 
180  /* Replace null characters with spaces. */
181  for (i = 0; i < len; ++i)
182  if (commandline[i] == '\0')
183  commandline[i] = ' ';
184 
185  commandline[len] = '\0';
186  }
187  else
188  {
189  /* Return the command in square brackets if the command-line
190  is empty. */
191  commandline = (char *) xmalloc (32);
192  commandline[0] = '[';
193  command_from_pid (commandline + 1, 31, pid);
194 
195  len = strlen (commandline);
196  if (len < 31)
197  strcat (commandline, "]");
198  }
199  }
200 
201  xfree (pathname);
202 
203  return commandline;
204 }
205 
206 /* Finds the user name for the user UID and copies it into USER. At
207  most MAXLEN characters are copied. */
208 
209 static void
210 user_from_uid (char *user, int maxlen, uid_t uid)
211 {
212  struct passwd *pwentry = getpwuid (uid);
213 
214  if (pwentry)
215  {
216  strncpy (user, pwentry->pw_name, maxlen);
217  /* Ensure that the user name is null-terminated. */
218  user[maxlen - 1] = '\0';
219  }
220  else
221  user[0] = '\0';
222 }
223 
224 /* Finds the owner of process PID and returns the user id in OWNER.
225  Returns 0 if the owner was found, -1 otherwise. */
226 
227 static int
228 get_process_owner (uid_t *owner, PID_T pid)
229 {
230  struct stat statbuf;
231  char procentry[sizeof ("/proc/") + MAX_PID_T_STRLEN];
232 
233  sprintf (procentry, "/proc/%lld", pid);
234 
235  if (stat (procentry, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
236  {
237  *owner = statbuf.st_uid;
238  return 0;
239  }
240  else
241  return -1;
242 }
243 
244 /* Find the CPU cores used by process PID and return them in CORES.
245  CORES points to an array of NUM_CORES elements. */
246 
247 static int
248 get_cores_used_by_process (PID_T pid, int *cores, const int num_cores)
249 {
250  char taskdir[sizeof ("/proc/") + MAX_PID_T_STRLEN + sizeof ("/task") - 1];
251  DIR *dir;
252  struct dirent *dp;
253  int task_count = 0;
254 
255  sprintf (taskdir, "/proc/%lld/task", pid);
256  dir = opendir (taskdir);
257  if (dir)
258  {
259  while ((dp = readdir (dir)) != NULL)
260  {
261  PID_T tid;
262  int core;
263 
264  if (!isdigit (dp->d_name[0])
265  || NAMELEN (dp) > MAX_PID_T_STRLEN)
266  continue;
267 
268  sscanf (dp->d_name, "%lld", &tid);
269  core = linux_common_core_of_thread (ptid_build ((pid_t) pid,
270  (pid_t) tid, 0));
271 
272  if (core >= 0 && core < num_cores)
273  {
274  ++cores[core];
275  ++task_count;
276  }
277  }
278 
279  closedir (dir);
280  }
281 
282  return task_count;
283 }
284 
285 static LONGEST
287  ULONGEST offset, ULONGEST len)
288 {
289  /* We make the process list snapshot when the object starts to be read. */
290  static const char *buf;
291  static LONGEST len_avail = -1;
292  static struct buffer buffer;
293 
294  if (offset == 0)
295  {
296  DIR *dirp;
297 
298  if (len_avail != -1 && len_avail != 0)
299  buffer_free (&buffer);
300  len_avail = 0;
301  buf = NULL;
302  buffer_init (&buffer);
303  buffer_grow_str (&buffer, "<osdata type=\"processes\">\n");
304 
305  dirp = opendir ("/proc");
306  if (dirp)
307  {
308  const int num_cores = sysconf (_SC_NPROCESSORS_ONLN);
309  struct dirent *dp;
310 
311  while ((dp = readdir (dirp)) != NULL)
312  {
313  PID_T pid;
314  uid_t owner;
315  char user[UT_NAMESIZE];
316  char *command_line;
317  int *cores;
318  int task_count;
319  char *cores_str;
320  int i;
321 
322  if (!isdigit (dp->d_name[0])
323  || NAMELEN (dp) > MAX_PID_T_STRLEN)
324  continue;
325 
326  sscanf (dp->d_name, "%lld", &pid);
327  command_line = commandline_from_pid (pid);
328 
329  if (get_process_owner (&owner, pid) == 0)
330  user_from_uid (user, sizeof (user), owner);
331  else
332  strcpy (user, "?");
333 
334  /* Find CPU cores used by the process. */
335  cores = XCNEWVEC (int, num_cores);
336  task_count = get_cores_used_by_process (pid, cores, num_cores);
337  cores_str = (char *) xcalloc (task_count, sizeof ("4294967295") + 1);
338 
339  for (i = 0; i < num_cores && task_count > 0; ++i)
340  if (cores[i])
341  {
342  char core_str[sizeof ("4294967295")];
343 
344  sprintf (core_str, "%d", i);
345  strcat (cores_str, core_str);
346 
347  task_count -= cores[i];
348  if (task_count > 0)
349  strcat (cores_str, ",");
350  }
351 
352  xfree (cores);
353 
355  &buffer,
356  "<item>"
357  "<column name=\"pid\">%lld</column>"
358  "<column name=\"user\">%s</column>"
359  "<column name=\"command\">%s</column>"
360  "<column name=\"cores\">%s</column>"
361  "</item>",
362  pid,
363  user,
364  command_line ? command_line : "",
365  cores_str);
366 
367  xfree (command_line);
368  xfree (cores_str);
369  }
370 
371  closedir (dirp);
372  }
373 
374  buffer_grow_str0 (&buffer, "</osdata>\n");
375  buf = buffer_finish (&buffer);
376  len_avail = strlen (buf);
377  }
378 
379  if (offset >= len_avail)
380  {
381  /* Done. Get rid of the buffer. */
382  buffer_free (&buffer);
383  buf = NULL;
384  len_avail = 0;
385  return 0;
386  }
387 
388  if (len > len_avail - offset)
389  len = len_avail - offset;
390  memcpy (readbuf, buf + offset, len);
391 
392  return len;
393 }
394 
395 /* A simple PID/PGID pair. */
396 
398 {
399  pid_pgid_entry (PID_T pid_, PID_T pgid_)
400  : pid (pid_), pgid (pgid_)
401  {}
402 
403  /* Return true if this pid is the leader of its process group. */
404 
405  bool is_leader () const
406  {
407  return pid == pgid;
408  }
409 
410  bool operator< (const pid_pgid_entry &other) const
411  {
412  /* Sort by PGID. */
413  if (this->pgid != other.pgid)
414  return this->pgid < other.pgid;
415 
416  /* Process group leaders always come first... */
417  if (this->is_leader ())
418  return true;
419 
420  if (other.is_leader ())
421  return false;
422 
423  /* ...else sort by PID. */
424  return this->pid < other.pid;
425  }
426 
428 };
429 
430 /* Collect all process groups from /proc. */
431 
432 static LONGEST
434  ULONGEST offset, ULONGEST len)
435 {
436  /* We make the process list snapshot when the object starts to be read. */
437  static const char *buf;
438  static LONGEST len_avail = -1;
439  static struct buffer buffer;
440 
441  if (offset == 0)
442  {
443  DIR *dirp;
444 
445  if (len_avail != -1 && len_avail != 0)
446  buffer_free (&buffer);
447  len_avail = 0;
448  buf = NULL;
449  buffer_init (&buffer);
450  buffer_grow_str (&buffer, "<osdata type=\"process groups\">\n");
451 
452  dirp = opendir ("/proc");
453  if (dirp)
454  {
455  std::vector<pid_pgid_entry> process_list;
456  struct dirent *dp;
457 
458  process_list.reserve (512);
459 
460  /* Build list consisting of PIDs followed by their
461  associated PGID. */
462  while ((dp = readdir (dirp)) != NULL)
463  {
464  PID_T pid, pgid;
465 
466  if (!isdigit (dp->d_name[0])
467  || NAMELEN (dp) > MAX_PID_T_STRLEN)
468  continue;
469 
470  sscanf (dp->d_name, "%lld", &pid);
471  pgid = getpgid (pid);
472 
473  if (pgid > 0)
474  process_list.emplace_back (pid, pgid);
475  }
476 
477  closedir (dirp);
478 
479  /* Sort the process list. */
480  std::sort (process_list.begin (), process_list.end ());
481 
482  for (const pid_pgid_entry &entry : process_list)
483  {
484  PID_T pid = entry.pid;
485  PID_T pgid = entry.pgid;
486  char leader_command[32];
487  char *command_line;
488 
489  command_from_pid (leader_command, sizeof (leader_command), pgid);
490  command_line = commandline_from_pid (pid);
491 
493  &buffer,
494  "<item>"
495  "<column name=\"pgid\">%lld</column>"
496  "<column name=\"leader command\">%s</column>"
497  "<column name=\"pid\">%lld</column>"
498  "<column name=\"command line\">%s</column>"
499  "</item>",
500  pgid,
501  leader_command,
502  pid,
503  command_line ? command_line : "");
504 
505  xfree (command_line);
506  }
507  }
508 
509  buffer_grow_str0 (&buffer, "</osdata>\n");
510  buf = buffer_finish (&buffer);
511  len_avail = strlen (buf);
512  }
513 
514  if (offset >= len_avail)
515  {
516  /* Done. Get rid of the buffer. */
517  buffer_free (&buffer);
518  buf = NULL;
519  len_avail = 0;
520  return 0;
521  }
522 
523  if (len > len_avail - offset)
524  len = len_avail - offset;
525  memcpy (readbuf, buf + offset, len);
526 
527  return len;
528 }
529 
530 /* Collect all the threads in /proc by iterating through processes and
531  then tasks within each process. */
532 
533 static LONGEST
535  ULONGEST offset, ULONGEST len)
536 {
537  /* We make the process list snapshot when the object starts to be read. */
538  static const char *buf;
539  static LONGEST len_avail = -1;
540  static struct buffer buffer;
541 
542  if (offset == 0)
543  {
544  DIR *dirp;
545 
546  if (len_avail != -1 && len_avail != 0)
547  buffer_free (&buffer);
548  len_avail = 0;
549  buf = NULL;
550  buffer_init (&buffer);
551  buffer_grow_str (&buffer, "<osdata type=\"threads\">\n");
552 
553  dirp = opendir ("/proc");
554  if (dirp)
555  {
556  struct dirent *dp;
557 
558  while ((dp = readdir (dirp)) != NULL)
559  {
560  struct stat statbuf;
561  char procentry[sizeof ("/proc/4294967295")];
562 
563  if (!isdigit (dp->d_name[0])
564  || NAMELEN (dp) > sizeof ("4294967295") - 1)
565  continue;
566 
567  xsnprintf (procentry, sizeof (procentry), "/proc/%s",
568  dp->d_name);
569  if (stat (procentry, &statbuf) == 0
570  && S_ISDIR (statbuf.st_mode))
571  {
572  DIR *dirp2;
573  char *pathname;
574  PID_T pid;
575  char command[32];
576 
577  pathname = xstrprintf ("/proc/%s/task", dp->d_name);
578 
579  pid = atoi (dp->d_name);
580  command_from_pid (command, sizeof (command), pid);
581 
582  dirp2 = opendir (pathname);
583 
584  if (dirp2)
585  {
586  struct dirent *dp2;
587 
588  while ((dp2 = readdir (dirp2)) != NULL)
589  {
590  PID_T tid;
591  int core;
592 
593  if (!isdigit (dp2->d_name[0])
594  || NAMELEN (dp2) > sizeof ("4294967295") - 1)
595  continue;
596 
597  tid = atoi (dp2->d_name);
598  core = linux_common_core_of_thread (ptid_build (pid, tid, 0));
599 
601  &buffer,
602  "<item>"
603  "<column name=\"pid\">%lld</column>"
604  "<column name=\"command\">%s</column>"
605  "<column name=\"tid\">%lld</column>"
606  "<column name=\"core\">%d</column>"
607  "</item>",
608  pid,
609  command,
610  tid,
611  core);
612  }
613 
614  closedir (dirp2);
615  }
616 
617  xfree (pathname);
618  }
619  }
620 
621  closedir (dirp);
622  }
623 
624  buffer_grow_str0 (&buffer, "</osdata>\n");
625  buf = buffer_finish (&buffer);
626  len_avail = strlen (buf);
627  }
628 
629  if (offset >= len_avail)
630  {
631  /* Done. Get rid of the buffer. */
632  buffer_free (&buffer);
633  buf = NULL;
634  len_avail = 0;
635  return 0;
636  }
637 
638  if (len > len_avail - offset)
639  len = len_avail - offset;
640  memcpy (readbuf, buf + offset, len);
641 
642  return len;
643 }
644 
645 /* Collect data about the cpus/cores on the system */
646 
647 static LONGEST
649  ULONGEST offset, ULONGEST len)
650 {
651  static const char *buf;
652  static LONGEST len_avail = -1;
653  static struct buffer buffer;
654 
655  if (offset == 0)
656  {
657  int first_item = 1;
658 
659  if (len_avail != -1 && len_avail != 0)
660  buffer_free (&buffer);
661  len_avail = 0;
662  buf = NULL;
663  buffer_init (&buffer);
664  buffer_grow_str (&buffer, "<osdata type=\"cpus\">\n");
665 
666  gdb_file_up fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
667  if (fp != NULL)
668  {
669  char buf[8192];
670 
671  do
672  {
673  if (fgets (buf, sizeof (buf), fp.get ()))
674  {
675  char *key, *value;
676  int i = 0;
677 
678  key = strtok (buf, ":");
679  if (key == NULL)
680  continue;
681 
682  value = strtok (NULL, ":");
683  if (value == NULL)
684  continue;
685 
686  while (key[i] != '\t' && key[i] != '\0')
687  i++;
688 
689  key[i] = '\0';
690 
691  i = 0;
692  while (value[i] != '\t' && value[i] != '\0')
693  i++;
694 
695  value[i] = '\0';
696 
697  if (strcmp (key, "processor") == 0)
698  {
699  if (first_item)
700  buffer_grow_str (&buffer, "<item>");
701  else
702  buffer_grow_str (&buffer, "</item><item>");
703 
704  first_item = 0;
705  }
706 
708  "<column name=\"%s\">%s</column>",
709  key,
710  value);
711  }
712  }
713  while (!feof (fp.get ()));
714 
715  if (first_item == 0)
716  buffer_grow_str (&buffer, "</item>");
717  }
718 
719  buffer_grow_str0 (&buffer, "</osdata>\n");
720  buf = buffer_finish (&buffer);
721  len_avail = strlen (buf);
722  }
723 
724  if (offset >= len_avail)
725  {
726  /* Done. Get rid of the buffer. */
727  buffer_free (&buffer);
728  buf = NULL;
729  len_avail = 0;
730  return 0;
731  }
732 
733  if (len > len_avail - offset)
734  len = len_avail - offset;
735  memcpy (readbuf, buf + offset, len);
736 
737  return len;
738 }
739 
740 /* Collect all the open file descriptors found in /proc and put the details
741  found about them into READBUF. */
742 
743 static LONGEST
745  ULONGEST offset, ULONGEST len)
746 {
747  /* We make the process list snapshot when the object starts to be read. */
748  static const char *buf;
749  static LONGEST len_avail = -1;
750  static struct buffer buffer;
751 
752  if (offset == 0)
753  {
754  DIR *dirp;
755 
756  if (len_avail != -1 && len_avail != 0)
757  buffer_free (&buffer);
758  len_avail = 0;
759  buf = NULL;
760  buffer_init (&buffer);
761  buffer_grow_str (&buffer, "<osdata type=\"files\">\n");
762 
763  dirp = opendir ("/proc");
764  if (dirp)
765  {
766  struct dirent *dp;
767 
768  while ((dp = readdir (dirp)) != NULL)
769  {
770  struct stat statbuf;
771  char procentry[sizeof ("/proc/4294967295")];
772 
773  if (!isdigit (dp->d_name[0])
774  || NAMELEN (dp) > sizeof ("4294967295") - 1)
775  continue;
776 
777  xsnprintf (procentry, sizeof (procentry), "/proc/%s",
778  dp->d_name);
779  if (stat (procentry, &statbuf) == 0
780  && S_ISDIR (statbuf.st_mode))
781  {
782  char *pathname;
783  DIR *dirp2;
784  PID_T pid;
785  char command[32];
786 
787  pid = atoi (dp->d_name);
788  command_from_pid (command, sizeof (command), pid);
789 
790  pathname = xstrprintf ("/proc/%s/fd", dp->d_name);
791  dirp2 = opendir (pathname);
792 
793  if (dirp2)
794  {
795  struct dirent *dp2;
796 
797  while ((dp2 = readdir (dirp2)) != NULL)
798  {
799  char *fdname;
800  char buf[1000];
801  ssize_t rslt;
802 
803  if (!isdigit (dp2->d_name[0]))
804  continue;
805 
806  fdname = xstrprintf ("%s/%s", pathname, dp2->d_name);
807  rslt = readlink (fdname, buf, sizeof (buf) - 1);
808  if (rslt >= 0)
809  buf[rslt] = '\0';
810 
812  &buffer,
813  "<item>"
814  "<column name=\"pid\">%s</column>"
815  "<column name=\"command\">%s</column>"
816  "<column name=\"file descriptor\">%s</column>"
817  "<column name=\"name\">%s</column>"
818  "</item>",
819  dp->d_name,
820  command,
821  dp2->d_name,
822  (rslt >= 0 ? buf : dp2->d_name));
823  }
824 
825  closedir (dirp2);
826  }
827 
828  xfree (pathname);
829  }
830  }
831 
832  closedir (dirp);
833  }
834 
835  buffer_grow_str0 (&buffer, "</osdata>\n");
836  buf = buffer_finish (&buffer);
837  len_avail = strlen (buf);
838  }
839 
840  if (offset >= len_avail)
841  {
842  /* Done. Get rid of the buffer. */
843  buffer_free (&buffer);
844  buf = NULL;
845  len_avail = 0;
846  return 0;
847  }
848 
849  if (len > len_avail - offset)
850  len = len_avail - offset;
851  memcpy (readbuf, buf + offset, len);
852 
853  return len;
854 }
855 
856 /* Returns the socket state STATE in textual form. */
857 
858 static const char *
859 format_socket_state (unsigned char state)
860 {
861  /* Copied from include/net/tcp_states.h in the Linux kernel sources. */
862  enum {
863  TCP_ESTABLISHED = 1,
864  TCP_SYN_SENT,
865  TCP_SYN_RECV,
866  TCP_FIN_WAIT1,
867  TCP_FIN_WAIT2,
868  TCP_TIME_WAIT,
869  TCP_CLOSE,
870  TCP_CLOSE_WAIT,
871  TCP_LAST_ACK,
872  TCP_LISTEN,
873  TCP_CLOSING
874  };
875 
876  switch (state)
877  {
878  case TCP_ESTABLISHED:
879  return "ESTABLISHED";
880  case TCP_SYN_SENT:
881  return "SYN_SENT";
882  case TCP_SYN_RECV:
883  return "SYN_RECV";
884  case TCP_FIN_WAIT1:
885  return "FIN_WAIT1";
886  case TCP_FIN_WAIT2:
887  return "FIN_WAIT2";
888  case TCP_TIME_WAIT:
889  return "TIME_WAIT";
890  case TCP_CLOSE:
891  return "CLOSE";
892  case TCP_CLOSE_WAIT:
893  return "CLOSE_WAIT";
894  case TCP_LAST_ACK:
895  return "LAST_ACK";
896  case TCP_LISTEN:
897  return "LISTEN";
898  case TCP_CLOSING:
899  return "CLOSING";
900  default:
901  return "(unknown)";
902  }
903 }
904 
906  {
907  struct sockaddr sa;
908  struct sockaddr_in sin;
909  struct sockaddr_in6 sin6;
910  };
911 
912 /* Auxiliary function used by linux_xfer_osdata_isocket. Formats
913  information for all open internet sockets of type FAMILY on the
914  system into BUFFER. If TCP is set, only TCP sockets are processed,
915  otherwise only UDP sockets are processed. */
916 
917 static void
918 print_sockets (unsigned short family, int tcp, struct buffer *buffer)
919 {
920  const char *proc_file;
921 
922  if (family == AF_INET)
923  proc_file = tcp ? "/proc/net/tcp" : "/proc/net/udp";
924  else if (family == AF_INET6)
925  proc_file = tcp ? "/proc/net/tcp6" : "/proc/net/udp6";
926  else
927  return;
928 
929  gdb_file_up fp = gdb_fopen_cloexec (proc_file, "r");
930  if (fp)
931  {
932  char buf[8192];
933 
934  do
935  {
936  if (fgets (buf, sizeof (buf), fp.get ()))
937  {
938  uid_t uid;
939  unsigned int local_port, remote_port, state;
940  char local_address[NI_MAXHOST], remote_address[NI_MAXHOST];
941  int result;
942 
943 #if NI_MAXHOST <= 32
944 #error "local_address and remote_address buffers too small"
945 #endif
946 
947  result = sscanf (buf,
948  "%*d: %32[0-9A-F]:%X %32[0-9A-F]:%X %X %*X:%*X %*X:%*X %*X %d %*d %*u %*s\n",
949  local_address, &local_port,
950  remote_address, &remote_port,
951  &state,
952  &uid);
953 
954  if (result == 6)
955  {
956  union socket_addr locaddr, remaddr;
957  size_t addr_size;
958  char user[UT_NAMESIZE];
959  char local_service[NI_MAXSERV], remote_service[NI_MAXSERV];
960 
961  if (family == AF_INET)
962  {
963  sscanf (local_address, "%X",
964  &locaddr.sin.sin_addr.s_addr);
965  sscanf (remote_address, "%X",
966  &remaddr.sin.sin_addr.s_addr);
967 
968  locaddr.sin.sin_port = htons (local_port);
969  remaddr.sin.sin_port = htons (remote_port);
970 
971  addr_size = sizeof (struct sockaddr_in);
972  }
973  else
974  {
975  sscanf (local_address, "%8X%8X%8X%8X",
976  locaddr.sin6.sin6_addr.s6_addr32,
977  locaddr.sin6.sin6_addr.s6_addr32 + 1,
978  locaddr.sin6.sin6_addr.s6_addr32 + 2,
979  locaddr.sin6.sin6_addr.s6_addr32 + 3);
980  sscanf (remote_address, "%8X%8X%8X%8X",
981  remaddr.sin6.sin6_addr.s6_addr32,
982  remaddr.sin6.sin6_addr.s6_addr32 + 1,
983  remaddr.sin6.sin6_addr.s6_addr32 + 2,
984  remaddr.sin6.sin6_addr.s6_addr32 + 3);
985 
986  locaddr.sin6.sin6_port = htons (local_port);
987  remaddr.sin6.sin6_port = htons (remote_port);
988 
989  locaddr.sin6.sin6_flowinfo = 0;
990  remaddr.sin6.sin6_flowinfo = 0;
991  locaddr.sin6.sin6_scope_id = 0;
992  remaddr.sin6.sin6_scope_id = 0;
993 
994  addr_size = sizeof (struct sockaddr_in6);
995  }
996 
997  locaddr.sa.sa_family = remaddr.sa.sa_family = family;
998 
999  result = getnameinfo (&locaddr.sa, addr_size,
1000  local_address, sizeof (local_address),
1001  local_service, sizeof (local_service),
1002  NI_NUMERICHOST | NI_NUMERICSERV
1003  | (tcp ? 0 : NI_DGRAM));
1004  if (result)
1005  continue;
1006 
1007  result = getnameinfo (&remaddr.sa, addr_size,
1008  remote_address,
1009  sizeof (remote_address),
1010  remote_service,
1011  sizeof (remote_service),
1012  NI_NUMERICHOST | NI_NUMERICSERV
1013  | (tcp ? 0 : NI_DGRAM));
1014  if (result)
1015  continue;
1016 
1017  user_from_uid (user, sizeof (user), uid);
1018 
1020  buffer,
1021  "<item>"
1022  "<column name=\"local address\">%s</column>"
1023  "<column name=\"local port\">%s</column>"
1024  "<column name=\"remote address\">%s</column>"
1025  "<column name=\"remote port\">%s</column>"
1026  "<column name=\"state\">%s</column>"
1027  "<column name=\"user\">%s</column>"
1028  "<column name=\"family\">%s</column>"
1029  "<column name=\"protocol\">%s</column>"
1030  "</item>",
1031  local_address,
1032  local_service,
1033  remote_address,
1034  remote_service,
1035  format_socket_state (state),
1036  user,
1037  (family == AF_INET) ? "INET" : "INET6",
1038  tcp ? "STREAM" : "DGRAM");
1039  }
1040  }
1041  }
1042  while (!feof (fp.get ()));
1043  }
1044 }
1045 
1046 /* Collect data about internet sockets and write it into READBUF. */
1047 
1048 static LONGEST
1050  ULONGEST offset, ULONGEST len)
1051 {
1052  static const char *buf;
1053  static LONGEST len_avail = -1;
1054  static struct buffer buffer;
1055 
1056  if (offset == 0)
1057  {
1058  if (len_avail != -1 && len_avail != 0)
1059  buffer_free (&buffer);
1060  len_avail = 0;
1061  buf = NULL;
1062  buffer_init (&buffer);
1063  buffer_grow_str (&buffer, "<osdata type=\"I sockets\">\n");
1064 
1065  print_sockets (AF_INET, 1, &buffer);
1066  print_sockets (AF_INET, 0, &buffer);
1067  print_sockets (AF_INET6, 1, &buffer);
1068  print_sockets (AF_INET6, 0, &buffer);
1069 
1070  buffer_grow_str0 (&buffer, "</osdata>\n");
1071  buf = buffer_finish (&buffer);
1072  len_avail = strlen (buf);
1073  }
1074 
1075  if (offset >= len_avail)
1076  {
1077  /* Done. Get rid of the buffer. */
1078  buffer_free (&buffer);
1079  buf = NULL;
1080  len_avail = 0;
1081  return 0;
1082  }
1083 
1084  if (len > len_avail - offset)
1085  len = len_avail - offset;
1086  memcpy (readbuf, buf + offset, len);
1087 
1088  return len;
1089 }
1090 
1091 /* Converts the time SECONDS into textual form and copies it into a
1092  buffer TIME, with at most MAXLEN characters copied. */
1093 
1094 static void
1095 time_from_time_t (char *time, int maxlen, TIME_T seconds)
1096 {
1097  if (!seconds)
1098  time[0] = '\0';
1099  else
1100  {
1101  time_t t = (time_t) seconds;
1102 
1103  strncpy (time, ctime (&t), maxlen);
1104  time[maxlen - 1] = '\0';
1105  }
1106 }
1107 
1108 /* Finds the group name for the group GID and copies it into GROUP.
1109  At most MAXLEN characters are copied. */
1110 
1111 static void
1112 group_from_gid (char *group, int maxlen, gid_t gid)
1113 {
1114  struct group *grentry = getgrgid (gid);
1115 
1116  if (grentry)
1117  {
1118  strncpy (group, grentry->gr_name, maxlen);
1119  /* Ensure that the group name is null-terminated. */
1120  group[maxlen - 1] = '\0';
1121  }
1122  else
1123  group[0] = '\0';
1124 }
1125 
1126 /* Collect data about shared memory recorded in /proc and write it
1127  into READBUF. */
1128 
1129 static LONGEST
1131  ULONGEST offset, ULONGEST len)
1132 {
1133  static const char *buf;
1134  static LONGEST len_avail = -1;
1135  static struct buffer buffer;
1136 
1137  if (offset == 0)
1138  {
1139  if (len_avail != -1 && len_avail != 0)
1140  buffer_free (&buffer);
1141  len_avail = 0;
1142  buf = NULL;
1143  buffer_init (&buffer);
1144  buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");
1145 
1146  gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
1147  if (fp)
1148  {
1149  char buf[8192];
1150 
1151  do
1152  {
1153  if (fgets (buf, sizeof (buf), fp.get ()))
1154  {
1155  key_t key;
1156  uid_t uid, cuid;
1157  gid_t gid, cgid;
1158  PID_T cpid, lpid;
1159  int shmid, size, nattch;
1160  TIME_T atime, dtime, ctime;
1161  unsigned int perms;
1162  int items_read;
1163 
1164  items_read = sscanf (buf,
1165  "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
1166  &key, &shmid, &perms, &size,
1167  &cpid, &lpid,
1168  &nattch,
1169  &uid, &gid, &cuid, &cgid,
1170  &atime, &dtime, &ctime);
1171 
1172  if (items_read == 14)
1173  {
1174  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1175  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1176  char ccmd[32], lcmd[32];
1177  char atime_str[32], dtime_str[32], ctime_str[32];
1178 
1179  user_from_uid (user, sizeof (user), uid);
1180  group_from_gid (group, sizeof (group), gid);
1181  user_from_uid (cuser, sizeof (cuser), cuid);
1182  group_from_gid (cgroup, sizeof (cgroup), cgid);
1183 
1184  command_from_pid (ccmd, sizeof (ccmd), cpid);
1185  command_from_pid (lcmd, sizeof (lcmd), lpid);
1186 
1187  time_from_time_t (atime_str, sizeof (atime_str), atime);
1188  time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
1189  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1190 
1192  &buffer,
1193  "<item>"
1194  "<column name=\"key\">%d</column>"
1195  "<column name=\"shmid\">%d</column>"
1196  "<column name=\"permissions\">%o</column>"
1197  "<column name=\"size\">%d</column>"
1198  "<column name=\"creator command\">%s</column>"
1199  "<column name=\"last op. command\">%s</column>"
1200  "<column name=\"num attached\">%d</column>"
1201  "<column name=\"user\">%s</column>"
1202  "<column name=\"group\">%s</column>"
1203  "<column name=\"creator user\">%s</column>"
1204  "<column name=\"creator group\">%s</column>"
1205  "<column name=\"last shmat() time\">%s</column>"
1206  "<column name=\"last shmdt() time\">%s</column>"
1207  "<column name=\"last shmctl() time\">%s</column>"
1208  "</item>",
1209  key,
1210  shmid,
1211  perms,
1212  size,
1213  ccmd,
1214  lcmd,
1215  nattch,
1216  user,
1217  group,
1218  cuser,
1219  cgroup,
1220  atime_str,
1221  dtime_str,
1222  ctime_str);
1223  }
1224  }
1225  }
1226  while (!feof (fp.get ()));
1227  }
1228 
1229  buffer_grow_str0 (&buffer, "</osdata>\n");
1230  buf = buffer_finish (&buffer);
1231  len_avail = strlen (buf);
1232  }
1233 
1234  if (offset >= len_avail)
1235  {
1236  /* Done. Get rid of the buffer. */
1237  buffer_free (&buffer);
1238  buf = NULL;
1239  len_avail = 0;
1240  return 0;
1241  }
1242 
1243  if (len > len_avail - offset)
1244  len = len_avail - offset;
1245  memcpy (readbuf, buf + offset, len);
1246 
1247  return len;
1248 }
1249 
1250 /* Collect data about semaphores recorded in /proc and write it
1251  into READBUF. */
1252 
1253 static LONGEST
1255  ULONGEST offset, ULONGEST len)
1256 {
1257  static const char *buf;
1258  static LONGEST len_avail = -1;
1259  static struct buffer buffer;
1260 
1261  if (offset == 0)
1262  {
1263  if (len_avail != -1 && len_avail != 0)
1264  buffer_free (&buffer);
1265  len_avail = 0;
1266  buf = NULL;
1267  buffer_init (&buffer);
1268  buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");
1269 
1270  gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
1271  if (fp)
1272  {
1273  char buf[8192];
1274 
1275  do
1276  {
1277  if (fgets (buf, sizeof (buf), fp.get ()))
1278  {
1279  key_t key;
1280  uid_t uid, cuid;
1281  gid_t gid, cgid;
1282  unsigned int perms, nsems;
1283  int semid;
1284  TIME_T otime, ctime;
1285  int items_read;
1286 
1287  items_read = sscanf (buf,
1288  "%d %d %o %u %d %d %d %d %lld %lld",
1289  &key, &semid, &perms, &nsems,
1290  &uid, &gid, &cuid, &cgid,
1291  &otime, &ctime);
1292 
1293  if (items_read == 10)
1294  {
1295  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1296  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1297  char otime_str[32], ctime_str[32];
1298 
1299  user_from_uid (user, sizeof (user), uid);
1300  group_from_gid (group, sizeof (group), gid);
1301  user_from_uid (cuser, sizeof (cuser), cuid);
1302  group_from_gid (cgroup, sizeof (cgroup), cgid);
1303 
1304  time_from_time_t (otime_str, sizeof (otime_str), otime);
1305  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1306 
1308  &buffer,
1309  "<item>"
1310  "<column name=\"key\">%d</column>"
1311  "<column name=\"semid\">%d</column>"
1312  "<column name=\"permissions\">%o</column>"
1313  "<column name=\"num semaphores\">%u</column>"
1314  "<column name=\"user\">%s</column>"
1315  "<column name=\"group\">%s</column>"
1316  "<column name=\"creator user\">%s</column>"
1317  "<column name=\"creator group\">%s</column>"
1318  "<column name=\"last semop() time\">%s</column>"
1319  "<column name=\"last semctl() time\">%s</column>"
1320  "</item>",
1321  key,
1322  semid,
1323  perms,
1324  nsems,
1325  user,
1326  group,
1327  cuser,
1328  cgroup,
1329  otime_str,
1330  ctime_str);
1331  }
1332  }
1333  }
1334  while (!feof (fp.get ()));
1335  }
1336 
1337  buffer_grow_str0 (&buffer, "</osdata>\n");
1338  buf = buffer_finish (&buffer);
1339  len_avail = strlen (buf);
1340  }
1341 
1342  if (offset >= len_avail)
1343  {
1344  /* Done. Get rid of the buffer. */
1345  buffer_free (&buffer);
1346  buf = NULL;
1347  len_avail = 0;
1348  return 0;
1349  }
1350 
1351  if (len > len_avail - offset)
1352  len = len_avail - offset;
1353  memcpy (readbuf, buf + offset, len);
1354 
1355  return len;
1356 }
1357 
1358 /* Collect data about message queues recorded in /proc and write it
1359  into READBUF. */
1360 
1361 static LONGEST
1363  ULONGEST offset, ULONGEST len)
1364 {
1365  static const char *buf;
1366  static LONGEST len_avail = -1;
1367  static struct buffer buffer;
1368 
1369  if (offset == 0)
1370  {
1371  if (len_avail != -1 && len_avail != 0)
1372  buffer_free (&buffer);
1373  len_avail = 0;
1374  buf = NULL;
1375  buffer_init (&buffer);
1376  buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
1377 
1378  gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
1379  if (fp)
1380  {
1381  char buf[8192];
1382 
1383  do
1384  {
1385  if (fgets (buf, sizeof (buf), fp.get ()))
1386  {
1387  key_t key;
1388  PID_T lspid, lrpid;
1389  uid_t uid, cuid;
1390  gid_t gid, cgid;
1391  unsigned int perms, cbytes, qnum;
1392  int msqid;
1393  TIME_T stime, rtime, ctime;
1394  int items_read;
1395 
1396  items_read = sscanf (buf,
1397  "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
1398  &key, &msqid, &perms, &cbytes, &qnum,
1399  &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
1400  &stime, &rtime, &ctime);
1401 
1402  if (items_read == 14)
1403  {
1404  char user[UT_NAMESIZE], group[UT_NAMESIZE];
1405  char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
1406  char lscmd[32], lrcmd[32];
1407  char stime_str[32], rtime_str[32], ctime_str[32];
1408 
1409  user_from_uid (user, sizeof (user), uid);
1410  group_from_gid (group, sizeof (group), gid);
1411  user_from_uid (cuser, sizeof (cuser), cuid);
1412  group_from_gid (cgroup, sizeof (cgroup), cgid);
1413 
1414  command_from_pid (lscmd, sizeof (lscmd), lspid);
1415  command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
1416 
1417  time_from_time_t (stime_str, sizeof (stime_str), stime);
1418  time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
1419  time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
1420 
1422  &buffer,
1423  "<item>"
1424  "<column name=\"key\">%d</column>"
1425  "<column name=\"msqid\">%d</column>"
1426  "<column name=\"permissions\">%o</column>"
1427  "<column name=\"num used bytes\">%u</column>"
1428  "<column name=\"num messages\">%u</column>"
1429  "<column name=\"last msgsnd() command\">%s</column>"
1430  "<column name=\"last msgrcv() command\">%s</column>"
1431  "<column name=\"user\">%s</column>"
1432  "<column name=\"group\">%s</column>"
1433  "<column name=\"creator user\">%s</column>"
1434  "<column name=\"creator group\">%s</column>"
1435  "<column name=\"last msgsnd() time\">%s</column>"
1436  "<column name=\"last msgrcv() time\">%s</column>"
1437  "<column name=\"last msgctl() time\">%s</column>"
1438  "</item>",
1439  key,
1440  msqid,
1441  perms,
1442  cbytes,
1443  qnum,
1444  lscmd,
1445  lrcmd,
1446  user,
1447  group,
1448  cuser,
1449  cgroup,
1450  stime_str,
1451  rtime_str,
1452  ctime_str);
1453  }
1454  }
1455  }
1456  while (!feof (fp.get ()));
1457  }
1458 
1459  buffer_grow_str0 (&buffer, "</osdata>\n");
1460  buf = buffer_finish (&buffer);
1461  len_avail = strlen (buf);
1462  }
1463 
1464  if (offset >= len_avail)
1465  {
1466  /* Done. Get rid of the buffer. */
1467  buffer_free (&buffer);
1468  buf = NULL;
1469  len_avail = 0;
1470  return 0;
1471  }
1472 
1473  if (len > len_avail - offset)
1474  len = len_avail - offset;
1475  memcpy (readbuf, buf + offset, len);
1476 
1477  return len;
1478 }
1479 
1480 /* Collect data about loaded kernel modules and write it into
1481  READBUF. */
1482 
1483 static LONGEST
1485  ULONGEST offset, ULONGEST len)
1486 {
1487  static const char *buf;
1488  static LONGEST len_avail = -1;
1489  static struct buffer buffer;
1490 
1491  if (offset == 0)
1492  {
1493  if (len_avail != -1 && len_avail != 0)
1494  buffer_free (&buffer);
1495  len_avail = 0;
1496  buf = NULL;
1497  buffer_init (&buffer);
1498  buffer_grow_str (&buffer, "<osdata type=\"modules\">\n");
1499 
1500  gdb_file_up fp = gdb_fopen_cloexec ("/proc/modules", "r");
1501  if (fp)
1502  {
1503  char buf[8192];
1504 
1505  do
1506  {
1507  if (fgets (buf, sizeof (buf), fp.get ()))
1508  {
1509  char *name, *dependencies, *status, *tmp;
1510  unsigned int size;
1511  unsigned long long address;
1512  int uses;
1513 
1514  name = strtok (buf, " ");
1515  if (name == NULL)
1516  continue;
1517 
1518  tmp = strtok (NULL, " ");
1519  if (tmp == NULL)
1520  continue;
1521  if (sscanf (tmp, "%u", &size) != 1)
1522  continue;
1523 
1524  tmp = strtok (NULL, " ");
1525  if (tmp == NULL)
1526  continue;
1527  if (sscanf (tmp, "%d", &uses) != 1)
1528  continue;
1529 
1530  dependencies = strtok (NULL, " ");
1531  if (dependencies == NULL)
1532  continue;
1533 
1534  status = strtok (NULL, " ");
1535  if (status == NULL)
1536  continue;
1537 
1538  tmp = strtok (NULL, "\n");
1539  if (tmp == NULL)
1540  continue;
1541  if (sscanf (tmp, "%llx", &address) != 1)
1542  continue;
1543 
1545  &buffer,
1546  "<item>"
1547  "<column name=\"name\">%s</column>"
1548  "<column name=\"size\">%u</column>"
1549  "<column name=\"num uses\">%d</column>"
1550  "<column name=\"dependencies\">%s</column>"
1551  "<column name=\"status\">%s</column>"
1552  "<column name=\"address\">%llx</column>"
1553  "</item>",
1554  name,
1555  size,
1556  uses,
1557  dependencies,
1558  status,
1559  address);
1560  }
1561  }
1562  while (!feof (fp.get ()));
1563  }
1564 
1565  buffer_grow_str0 (&buffer, "</osdata>\n");
1566  buf = buffer_finish (&buffer);
1567  len_avail = strlen (buf);
1568  }
1569 
1570  if (offset >= len_avail)
1571  {
1572  /* Done. Get rid of the buffer. */
1573  buffer_free (&buffer);
1574  buf = NULL;
1575  len_avail = 0;
1576  return 0;
1577  }
1578 
1579  if (len > len_avail - offset)
1580  len = len_avail - offset;
1581  memcpy (readbuf, buf + offset, len);
1582 
1583  return len;
1584 }
1585 
1586 struct osdata_type {
1587  const char *type;
1588  const char *title;
1589  const char *description;
1591 } osdata_table[] = {
1592  { "cpus", "CPUs", "Listing of all cpus/cores on the system",
1594  { "files", "File descriptors", "Listing of all file descriptors",
1596  { "modules", "Kernel modules", "Listing of all loaded kernel modules",
1598  { "msg", "Message queues", "Listing of all message queues",
1600  { "processes", "Processes", "Listing of all processes",
1602  { "procgroups", "Process groups", "Listing of all process groups",
1604  { "semaphores", "Semaphores", "Listing of all semaphores",
1606  { "shm", "Shared-memory regions", "Listing of all shared-memory regions",
1608  { "sockets", "Sockets", "Listing of all internet-domain sockets",
1610  { "threads", "Threads", "Listing of all threads",
1612  { NULL, NULL, NULL }
1613 };
1614 
1615 LONGEST
1616 linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
1617  ULONGEST offset, ULONGEST len)
1618 {
1619  if (!annex || *annex == '\0')
1620  {
1621  static const char *buf;
1622  static LONGEST len_avail = -1;
1623  static struct buffer buffer;
1624 
1625  if (offset == 0)
1626  {
1627  int i;
1628 
1629  if (len_avail != -1 && len_avail != 0)
1630  buffer_free (&buffer);
1631  len_avail = 0;
1632  buf = NULL;
1633  buffer_init (&buffer);
1634  buffer_grow_str (&buffer, "<osdata type=\"types\">\n");
1635 
1636  for (i = 0; osdata_table[i].type; ++i)
1638  &buffer,
1639  "<item>"
1640  "<column name=\"Type\">%s</column>"
1641  "<column name=\"Description\">%s</column>"
1642  "<column name=\"Title\">%s</column>"
1643  "</item>",
1644  osdata_table[i].type,
1645  osdata_table[i].description,
1646  osdata_table[i].title);
1647 
1648  buffer_grow_str0 (&buffer, "</osdata>\n");
1649  buf = buffer_finish (&buffer);
1650  len_avail = strlen (buf);
1651  }
1652 
1653  if (offset >= len_avail)
1654  {
1655  /* Done. Get rid of the buffer. */
1656  buffer_free (&buffer);
1657  buf = NULL;
1658  len_avail = 0;
1659  return 0;
1660  }
1661 
1662  if (len > len_avail - offset)
1663  len = len_avail - offset;
1664  memcpy (readbuf, buf + offset, len);
1665 
1666  return len;
1667  }
1668  else
1669  {
1670  int i;
1671 
1672  for (i = 0; osdata_table[i].type; ++i)
1673  {
1674  if (strcmp (annex, osdata_table[i].type) == 0)
1675  {
1676  gdb_assert (readbuf);
1677 
1678  return (osdata_table[i].getter) (readbuf, offset, len);
1679  }
1680  }
1681 
1682  return 0;
1683  }
1684 }
static void xfree(T *ptr)
Definition: common-utils.h:54
PID_T pid
Definition: linux-osdata.c:427
static void group_from_gid(char *group, int maxlen, gid_t gid)
#define MAX_PID_T_STRLEN
Definition: linux-osdata.c:55
static const struct aarch64_register fp
int ptid_get_pid(const ptid_t &ptid)
Definition: ptid.c:47
static LONGEST linux_xfer_osdata_modules(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
static LONGEST linux_xfer_osdata_isockets(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
static LONGEST linux_xfer_osdata_shm(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
struct sockaddr_in6 sin6
Definition: linux-osdata.c:909
static LONGEST linux_xfer_osdata_fds(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:744
void buffer_free(struct buffer *buffer)
Definition: buffer.c:48
static LONGEST linux_xfer_osdata_cpus(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:648
static void user_from_uid(char *user, int maxlen, uid_t uid)
Definition: linux-osdata.c:210
const char * name
Definition: tracepoint.c:180
static LONGEST linux_xfer_osdata_msg(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
bool is_leader() const
Definition: linux-osdata.c:405
ptid_t ptid_build(int pid, long lwp, long tid)
Definition: ptid.c:31
static LONGEST linux_xfer_osdata_processgroups(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:433
#define XCNEWVEC(T, N)
Definition: poison.h:157
const char * title
std::unique_ptr< FILE, gdb_file_deleter > gdb_file_up
Definition: filestuff.h:59
struct osdata_type osdata_table[]
PID_T pgid
Definition: linux-osdata.c:427
static void print_sockets(unsigned short family, int tcp, struct buffer *buffer)
Definition: linux-osdata.c:918
void buffer_xml_printf(struct buffer *buffer, const char *format,...)
Definition: buffer.c:76
static int get_process_owner(uid_t *owner, PID_T pid)
Definition: linux-osdata.c:228
static void command_from_pid(char *command, int maxlen, PID_T pid)
Definition: linux-osdata.c:116
Definition: ptid.h:35
Definition: linux-osdata.c:397
int offset
Definition: tracepoint.c:181
pid_pgid_entry(PID_T pid_, PID_T pgid_)
Definition: linux-osdata.c:399
struct sockaddr_in sin
Definition: linux-osdata.c:908
LONGEST(* getter)(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
int linux_common_core_of_thread(ptid_t ptid)
Definition: linux-osdata.c:62
gdb_file_up gdb_fopen_cloexec(const char *filename, const char *opentype)
Definition: filestuff.c:296
long long PID_T
Definition: linux-osdata.c:48
char * xstrprintf(const char *format,...)
Definition: common-utils.c:107
#define buffer_grow_str(BUFFER, STRING)
Definition: buffer.h:63
long ptid_get_lwp(const ptid_t &ptid)
Definition: ptid.c:55
static char * commandline_from_pid(PID_T pid)
Definition: linux-osdata.c:153
#define gdb_assert(expr)
Definition: gdb_assert.h:32
static LONGEST linux_xfer_osdata_processes(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:286
LONGEST linux_common_xfer_osdata(const char *annex, gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
PTR xrealloc(PTR ptr, size_t size)
Definition: common-utils.c:52
struct sockaddr sa
Definition: linux-osdata.c:907
#define buffer_grow_str0(BUFFER, STRING)
Definition: buffer.h:65
bfd_byte gdb_byte
Definition: common-types.h:38
void buffer_init(struct buffer *buffer)
Definition: buffer.c:60
int xsnprintf(char *str, size_t size, const char *format,...)
Definition: common-utils.c:134
Definition: buffer.h:23
static void time_from_time_t(char *time, int maxlen, TIME_T seconds)
const char * description
unsigned long long ULONGEST
Definition: common-types.h:53
PTR xmalloc(size_t size)
Definition: common-utils.c:35
long long TIME_T
Definition: linux-osdata.c:53
#define S_ISDIR(m)
Definition: stat.h:466
static LONGEST linux_xfer_osdata_threads(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
Definition: linux-osdata.c:534
static LONGEST linux_xfer_osdata_sem(gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
#define NAMELEN(dirent)
Definition: linux-osdata.c:42
static int get_cores_used_by_process(PID_T pid, int *cores, const int num_cores)
Definition: linux-osdata.c:248
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:72
char * buffer_finish(struct buffer *buffer)
Definition: buffer.c:66
long long LONGEST
Definition: common-types.h:52
bool operator<(const pid_pgid_entry &other) const
Definition: linux-osdata.c:410
const char * type
static const char * format_socket_state(unsigned char state)
Definition: linux-osdata.c:859