aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>2018-12-08 17:28:31 +0100
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>2018-12-11 23:00:47 +0100
commit750b258ef80992e76a3b03fe57dc9517e63de7f5 (patch)
tree64eea6a7e5a3b688326179aed0bc61e4fabae40a
parent9f375018392171cb46dce2c929ee979c67035f26 (diff)
downloadgdb-750b258ef80992e76a3b03fe57dc9517e63de7f5.zip
gdb-750b258ef80992e76a3b03fe57dc9517e63de7f5.tar.gz
gdb-750b258ef80992e76a3b03fe57dc9517e63de7f5.tar.bz2
Fix leaks in all the linux osdata annex transfers + code factorization.
Valgrind reports leaks in all linux osdata annex transfers of linux-osdata.c. A typical leak (this one is of gdb.base/info-os) is: ==10592== VALGRIND_GDB_ERROR_BEGIN ==10592== 65,536 bytes in 1 blocks are definitely lost in loss record 3,175 of 3,208 ==10592== at 0x4C2E273: realloc (vg_replace_malloc.c:826) ==10592== by 0x409B0C: xrealloc (common-utils.c:62) ==10592== by 0x408BC3: buffer_grow(buffer*, char const*, unsigned long) [clone .part.1] (buffer.c:40) ==10592== by 0x5263DF: linux_xfer_osdata_processes(unsigned char*, unsigned long, unsigned long) (linux-osdata.c:370) ==10592== by 0x520875: linux_nat_xfer_osdata (linux-nat.c:4214) ... The leaks are created because the linux_xfer_osdata_* functions transfer the ownership of their 'static struct buffer' memory to their 'static char *buf' local var, but then call buffer_free instead of xfree-ing buf. I see no reason why the ownership of the memory has to be transferred from a local var to another local var, so the fix consists in dropping the 'static char *buf' and accessing the struct buffer memory where needed. Also, because this bug was replicated in all functions, and there was a non neglectible amount of duplicated code, the setup and usage of the 'static struct buffer' is factorized in a new function common_getter. The buffer for a specific annex is now a member of the struct osdata_type instead of being a static var of each linux_xfer_osdata_* function. Thanks to this, all the linux_xfer_osdata_* do not have anymore any logic related to the partial transfer of data: they now only build the xml data in a struct buffer. This all removes about 300 SLOC. Note: git diff/git format-patch shows a lot of differences only due to space changes/indentation changes. So, git diff -w helps to look only at the relevant differences. gdb/ChangeLog 2018-12-11 Philippe Waroquiers <philippe.waroquiers@skynet.be> * nat/linux-osdata.c (common_getter): New function. (struct osdata_type): Change getter to take_snapshot. Add LONGEST len_avail and struct buffer buffer. Change all elements in the initializer. Add an element for the list of types. (linux_xfer_osdata_info_os_types): New function. (linux_common_xfer_osdata): Use common_getter for the list of types. Replace getter call by common_getter. (linux_xfer_osdata_cpus): Remove args READBUF, OFFSET, LEN. Add arg BUFFER. Only keep the code that adds data in BUFFER. (linux_xfer_osdata_fds): Likewise. (linux_xfer_osdata_modules): Likewise. (linux_xfer_osdata_msg): Likewise. (linux_xfer_osdata_processes): Likewise. (linux_xfer_osdata_processgroups): Likewise. (linux_xfer_osdata_sem): Likewise. (linux_xfer_osdata_shm): Likewise. (linux_xfer_osdata_isockets): Likewise. (linux_xfer_osdata_threads): Likewise.
-rw-r--r--gdb/ChangeLog22
-rw-r--r--gdb/nat/linux-osdata.c1569
2 files changed, 662 insertions, 929 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 04904c6..3d35d3b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,27 @@
2018-12-11 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+ * nat/linux-osdata.c (common_getter): New function.
+ (struct osdata_type): Change getter to take_snapshot.
+ Add LONGEST len_avail and struct buffer buffer.
+ Change all elements in the initializer.
+ Add an element for the list of types.
+ (linux_xfer_osdata_info_os_types): New function.
+ (linux_common_xfer_osdata): Use common_getter for the list of types.
+ Replace getter call by common_getter.
+ (linux_xfer_osdata_cpus): Remove args READBUF, OFFSET, LEN.
+ Add arg BUFFER. Only keep the code that adds data in BUFFER.
+ (linux_xfer_osdata_fds): Likewise.
+ (linux_xfer_osdata_modules): Likewise.
+ (linux_xfer_osdata_msg): Likewise.
+ (linux_xfer_osdata_processes): Likewise.
+ (linux_xfer_osdata_processgroups): Likewise.
+ (linux_xfer_osdata_sem): Likewise.
+ (linux_xfer_osdata_shm): Likewise.
+ (linux_xfer_osdata_isockets): Likewise.
+ (linux_xfer_osdata_threads): Likewise.
+
+2018-12-11 Philippe Waroquiers <philippe.waroquiers@skynet.be>
+
* nat/linux-osdata.c: Removed various trailing spaces.
2018-12-10 Andrew Burgess <andrew.burgess@embecosm.com>
diff --git a/gdb/nat/linux-osdata.c b/gdb/nat/linux-osdata.c
index 62ab42d..baca7fe 100644
--- a/gdb/nat/linux-osdata.c
+++ b/gdb/nat/linux-osdata.c
@@ -278,114 +278,83 @@ get_cores_used_by_process (PID_T pid, int *cores, const int num_cores)
return task_count;
}
-static LONGEST
-linux_xfer_osdata_processes (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_processes (struct buffer *buffer)
{
- /* We make the process list snapshot when the object starts to be read. */
- static const char *buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ DIR *dirp;
- if (offset == 0)
- {
- DIR *dirp;
+ buffer_grow_str (buffer, "<osdata type=\"processes\">\n");
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"processes\">\n");
+ dirp = opendir ("/proc");
+ if (dirp)
+ {
+ const int num_cores = sysconf (_SC_NPROCESSORS_ONLN);
+ struct dirent *dp;
- dirp = opendir ("/proc");
- if (dirp)
+ while ((dp = readdir (dirp)) != NULL)
{
- const int num_cores = sysconf (_SC_NPROCESSORS_ONLN);
- struct dirent *dp;
-
- while ((dp = readdir (dirp)) != NULL)
- {
- PID_T pid;
- uid_t owner;
- char user[UT_NAMESIZE];
- char *command_line;
- int *cores;
- int task_count;
- char *cores_str;
- int i;
-
- if (!isdigit (dp->d_name[0])
- || NAMELEN (dp) > MAX_PID_T_STRLEN)
- continue;
+ PID_T pid;
+ uid_t owner;
+ char user[UT_NAMESIZE];
+ char *command_line;
+ int *cores;
+ int task_count;
+ char *cores_str;
+ int i;
- sscanf (dp->d_name, "%lld", &pid);
- command_line = commandline_from_pid (pid);
-
- if (get_process_owner (&owner, pid) == 0)
- user_from_uid (user, sizeof (user), owner);
- else
- strcpy (user, "?");
-
- /* Find CPU cores used by the process. */
- cores = XCNEWVEC (int, num_cores);
- task_count = get_cores_used_by_process (pid, cores, num_cores);
- cores_str = (char *) xcalloc (task_count, sizeof ("4294967295") + 1);
-
- for (i = 0; i < num_cores && task_count > 0; ++i)
- if (cores[i])
- {
- char core_str[sizeof ("4294967295")];
-
- sprintf (core_str, "%d", i);
- strcat (cores_str, core_str);
-
- task_count -= cores[i];
- if (task_count > 0)
- strcat (cores_str, ",");
- }
-
- xfree (cores);
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"pid\">%lld</column>"
- "<column name=\"user\">%s</column>"
- "<column name=\"command\">%s</column>"
- "<column name=\"cores\">%s</column>"
- "</item>",
- pid,
- user,
- command_line ? command_line : "",
- cores_str);
-
- xfree (command_line);
- xfree (cores_str);
- }
+ if (!isdigit (dp->d_name[0])
+ || NAMELEN (dp) > MAX_PID_T_STRLEN)
+ continue;
- closedir (dirp);
+ sscanf (dp->d_name, "%lld", &pid);
+ command_line = commandline_from_pid (pid);
+
+ if (get_process_owner (&owner, pid) == 0)
+ user_from_uid (user, sizeof (user), owner);
+ else
+ strcpy (user, "?");
+
+ /* Find CPU cores used by the process. */
+ cores = XCNEWVEC (int, num_cores);
+ task_count = get_cores_used_by_process (pid, cores, num_cores);
+ cores_str = (char *) xcalloc (task_count, sizeof ("4294967295") + 1);
+
+ for (i = 0; i < num_cores && task_count > 0; ++i)
+ if (cores[i])
+ {
+ char core_str[sizeof ("4294967295")];
+
+ sprintf (core_str, "%d", i);
+ strcat (cores_str, core_str);
+
+ task_count -= cores[i];
+ if (task_count > 0)
+ strcat (cores_str, ",");
+ }
+
+ xfree (cores);
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"pid\">%lld</column>"
+ "<column name=\"user\">%s</column>"
+ "<column name=\"command\">%s</column>"
+ "<column name=\"cores\">%s</column>"
+ "</item>",
+ pid,
+ user,
+ command_line ? command_line : "",
+ cores_str);
+
+ xfree (command_line);
+ xfree (cores_str);
}
- buffer_grow_str0 (&buffer, "</osdata>\n");
- buf = buffer_finish (&buffer);
- len_avail = strlen (buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- buf = NULL;
- len_avail = 0;
- return 0;
+ closedir (dirp);
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* A simple PID/PGID pair. */
@@ -425,428 +394,305 @@ struct pid_pgid_entry
PID_T pid, pgid;
};
-/* Collect all process groups from /proc. */
+/* Collect all process groups from /proc in BUFFER. */
-static LONGEST
-linux_xfer_osdata_processgroups (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_processgroups (struct buffer *buffer)
{
- /* We make the process list snapshot when the object starts to be read. */
- static const char *buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ DIR *dirp;
- if (offset == 0)
+ buffer_grow_str (buffer, "<osdata type=\"process groups\">\n");
+
+ dirp = opendir ("/proc");
+ if (dirp)
{
- DIR *dirp;
+ std::vector<pid_pgid_entry> process_list;
+ struct dirent *dp;
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"process groups\">\n");
+ process_list.reserve (512);
- dirp = opendir ("/proc");
- if (dirp)
+ /* Build list consisting of PIDs followed by their
+ associated PGID. */
+ while ((dp = readdir (dirp)) != NULL)
{
- std::vector<pid_pgid_entry> process_list;
- struct dirent *dp;
-
- process_list.reserve (512);
+ PID_T pid, pgid;
- /* Build list consisting of PIDs followed by their
- associated PGID. */
- while ((dp = readdir (dirp)) != NULL)
- {
- PID_T pid, pgid;
-
- if (!isdigit (dp->d_name[0])
- || NAMELEN (dp) > MAX_PID_T_STRLEN)
- continue;
+ if (!isdigit (dp->d_name[0])
+ || NAMELEN (dp) > MAX_PID_T_STRLEN)
+ continue;
- sscanf (dp->d_name, "%lld", &pid);
- pgid = getpgid (pid);
+ sscanf (dp->d_name, "%lld", &pid);
+ pgid = getpgid (pid);
- if (pgid > 0)
- process_list.emplace_back (pid, pgid);
- }
+ if (pgid > 0)
+ process_list.emplace_back (pid, pgid);
+ }
- closedir (dirp);
+ closedir (dirp);
- /* Sort the process list. */
- std::sort (process_list.begin (), process_list.end ());
+ /* Sort the process list. */
+ std::sort (process_list.begin (), process_list.end ());
- for (const pid_pgid_entry &entry : process_list)
- {
- PID_T pid = entry.pid;
- PID_T pgid = entry.pgid;
- char leader_command[32];
- char *command_line;
-
- command_from_pid (leader_command, sizeof (leader_command), pgid);
- command_line = commandline_from_pid (pid);
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"pgid\">%lld</column>"
- "<column name=\"leader command\">%s</column>"
- "<column name=\"pid\">%lld</column>"
- "<column name=\"command line\">%s</column>"
- "</item>",
- pgid,
- leader_command,
- pid,
- command_line ? command_line : "");
-
- xfree (command_line);
- }
+ for (const pid_pgid_entry &entry : process_list)
+ {
+ PID_T pid = entry.pid;
+ PID_T pgid = entry.pgid;
+ char leader_command[32];
+ char *command_line;
+
+ command_from_pid (leader_command, sizeof (leader_command), pgid);
+ command_line = commandline_from_pid (pid);
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"pgid\">%lld</column>"
+ "<column name=\"leader command\">%s</column>"
+ "<column name=\"pid\">%lld</column>"
+ "<column name=\"command line\">%s</column>"
+ "</item>",
+ pgid,
+ leader_command,
+ pid,
+ command_line ? command_line : "");
+
+ xfree (command_line);
}
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- buf = buffer_finish (&buffer);
- len_avail = strlen (buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- buf = NULL;
- len_avail = 0;
- return 0;
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Collect all the threads in /proc by iterating through processes and
- then tasks within each process. */
+ then tasks within each process in BUFFER. */
-static LONGEST
-linux_xfer_osdata_threads (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_threads (struct buffer *buffer)
{
- /* We make the process list snapshot when the object starts to be read. */
- static const char *buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ DIR *dirp;
- if (offset == 0)
- {
- DIR *dirp;
+ buffer_grow_str (buffer, "<osdata type=\"threads\">\n");
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"threads\">\n");
+ dirp = opendir ("/proc");
+ if (dirp)
+ {
+ struct dirent *dp;
- dirp = opendir ("/proc");
- if (dirp)
+ while ((dp = readdir (dirp)) != NULL)
{
- struct dirent *dp;
+ struct stat statbuf;
+ char procentry[sizeof ("/proc/4294967295")];
- while ((dp = readdir (dirp)) != NULL)
- {
- struct stat statbuf;
- char procentry[sizeof ("/proc/4294967295")];
+ if (!isdigit (dp->d_name[0])
+ || NAMELEN (dp) > sizeof ("4294967295") - 1)
+ continue;
- if (!isdigit (dp->d_name[0])
- || NAMELEN (dp) > sizeof ("4294967295") - 1)
- continue;
+ xsnprintf (procentry, sizeof (procentry), "/proc/%s",
+ dp->d_name);
+ if (stat (procentry, &statbuf) == 0
+ && S_ISDIR (statbuf.st_mode))
+ {
+ DIR *dirp2;
+ PID_T pid;
+ char command[32];
- xsnprintf (procentry, sizeof (procentry), "/proc/%s",
- dp->d_name);
- if (stat (procentry, &statbuf) == 0
- && S_ISDIR (statbuf.st_mode))
- {
- DIR *dirp2;
- PID_T pid;
- char command[32];
+ std::string pathname
+ = string_printf ("/proc/%s/task", dp->d_name);
- std::string pathname
- = string_printf ("/proc/%s/task", dp->d_name);
+ pid = atoi (dp->d_name);
+ command_from_pid (command, sizeof (command), pid);
- pid = atoi (dp->d_name);
- command_from_pid (command, sizeof (command), pid);
+ dirp2 = opendir (pathname.c_str ());
- dirp2 = opendir (pathname.c_str ());
+ if (dirp2)
+ {
+ struct dirent *dp2;
- if (dirp2)
+ while ((dp2 = readdir (dirp2)) != NULL)
{
- struct dirent *dp2;
-
- while ((dp2 = readdir (dirp2)) != NULL)
- {
- PID_T tid;
- int core;
-
- if (!isdigit (dp2->d_name[0])
- || NAMELEN (dp2) > sizeof ("4294967295") - 1)
- continue;
-
- tid = atoi (dp2->d_name);
- core = linux_common_core_of_thread (ptid_t (pid, tid, 0));
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"pid\">%lld</column>"
- "<column name=\"command\">%s</column>"
- "<column name=\"tid\">%lld</column>"
- "<column name=\"core\">%d</column>"
- "</item>",
- pid,
- command,
- tid,
- core);
- }
-
- closedir (dirp2);
+ PID_T tid;
+ int core;
+
+ if (!isdigit (dp2->d_name[0])
+ || NAMELEN (dp2) > sizeof ("4294967295") - 1)
+ continue;
+
+ tid = atoi (dp2->d_name);
+ core = linux_common_core_of_thread (ptid_t (pid, tid, 0));
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"pid\">%lld</column>"
+ "<column name=\"command\">%s</column>"
+ "<column name=\"tid\">%lld</column>"
+ "<column name=\"core\">%d</column>"
+ "</item>",
+ pid,
+ command,
+ tid,
+ core);
}
+
+ closedir (dirp2);
}
}
-
- closedir (dirp);
}
- buffer_grow_str0 (&buffer, "</osdata>\n");
- buf = buffer_finish (&buffer);
- len_avail = strlen (buf);
+ closedir (dirp);
}
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- buf = NULL;
- len_avail = 0;
- return 0;
- }
-
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
-/* Collect data about the cpus/cores on the system */
+/* Collect data about the cpus/cores on the system in BUFFER. */
-static LONGEST
-linux_xfer_osdata_cpus (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_cpus (struct buffer *buffer)
{
- static const char *saved_buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ int first_item = 1;
- if (offset == 0)
- {
- int first_item = 1;
+ buffer_grow_str (buffer, "<osdata type=\"cpus\">\n");
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- saved_buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"cpus\">\n");
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
+ if (fp != NULL)
+ {
+ char buf[8192];
- gdb_file_up fp = gdb_fopen_cloexec ("/proc/cpuinfo", "r");
- if (fp != NULL)
+ do
{
- char buf[8192];
-
- do
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
- if (fgets (buf, sizeof (buf), fp.get ()))
- {
- char *key, *value;
- int i = 0;
+ char *key, *value;
+ int i = 0;
- key = strtok (buf, ":");
- if (key == NULL)
- continue;
-
- value = strtok (NULL, ":");
- if (value == NULL)
- continue;
+ key = strtok (buf, ":");
+ if (key == NULL)
+ continue;
- while (key[i] != '\t' && key[i] != '\0')
- i++;
+ value = strtok (NULL, ":");
+ if (value == NULL)
+ continue;
- key[i] = '\0';
+ while (key[i] != '\t' && key[i] != '\0')
+ i++;
- i = 0;
- while (value[i] != '\t' && value[i] != '\0')
- i++;
+ key[i] = '\0';
- value[i] = '\0';
+ i = 0;
+ while (value[i] != '\t' && value[i] != '\0')
+ i++;
- if (strcmp (key, "processor") == 0)
- {
- if (first_item)
- buffer_grow_str (&buffer, "<item>");
- else
- buffer_grow_str (&buffer, "</item><item>");
+ value[i] = '\0';
- first_item = 0;
- }
+ if (strcmp (key, "processor") == 0)
+ {
+ if (first_item)
+ buffer_grow_str (buffer, "<item>");
+ else
+ buffer_grow_str (buffer, "</item><item>");
- buffer_xml_printf (&buffer,
- "<column name=\"%s\">%s</column>",
- key,
- value);
+ first_item = 0;
}
- }
- while (!feof (fp.get ()));
- if (first_item == 0)
- buffer_grow_str (&buffer, "</item>");
+ buffer_xml_printf (buffer,
+ "<column name=\"%s\">%s</column>",
+ key,
+ value);
+ }
}
+ while (!feof (fp.get ()));
- buffer_grow_str0 (&buffer, "</osdata>\n");
- saved_buf = buffer_finish (&buffer);
- len_avail = strlen (saved_buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- saved_buf = NULL;
- len_avail = 0;
- return 0;
+ if (first_item == 0)
+ buffer_grow_str (buffer, "</item>");
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, saved_buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Collect all the open file descriptors found in /proc and put the details
- found about them into READBUF. */
+ found about them into BUFFER. */
-static LONGEST
-linux_xfer_osdata_fds (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_fds (struct buffer *buffer)
{
- /* We make the process list snapshot when the object starts to be read. */
- static const char *saved_buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ DIR *dirp;
- if (offset == 0)
- {
- DIR *dirp;
+ buffer_grow_str (buffer, "<osdata type=\"files\">\n");
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- saved_buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"files\">\n");
+ dirp = opendir ("/proc");
+ if (dirp)
+ {
+ struct dirent *dp;
- dirp = opendir ("/proc");
- if (dirp)
+ while ((dp = readdir (dirp)) != NULL)
{
- struct dirent *dp;
+ struct stat statbuf;
+ char procentry[sizeof ("/proc/4294967295")];
- while ((dp = readdir (dirp)) != NULL)
- {
- struct stat statbuf;
- char procentry[sizeof ("/proc/4294967295")];
+ if (!isdigit (dp->d_name[0])
+ || NAMELEN (dp) > sizeof ("4294967295") - 1)
+ continue;
- if (!isdigit (dp->d_name[0])
- || NAMELEN (dp) > sizeof ("4294967295") - 1)
- continue;
+ xsnprintf (procentry, sizeof (procentry), "/proc/%s",
+ dp->d_name);
+ if (stat (procentry, &statbuf) == 0
+ && S_ISDIR (statbuf.st_mode))
+ {
+ DIR *dirp2;
+ PID_T pid;
+ char command[32];
- xsnprintf (procentry, sizeof (procentry), "/proc/%s",
- dp->d_name);
- if (stat (procentry, &statbuf) == 0
- && S_ISDIR (statbuf.st_mode))
- {
- DIR *dirp2;
- PID_T pid;
- char command[32];
+ pid = atoi (dp->d_name);
+ command_from_pid (command, sizeof (command), pid);
- pid = atoi (dp->d_name);
- command_from_pid (command, sizeof (command), pid);
+ std::string pathname
+ = string_printf ("/proc/%s/fd", dp->d_name);
+ dirp2 = opendir (pathname.c_str ());
- std::string pathname
- = string_printf ("/proc/%s/fd", dp->d_name);
- dirp2 = opendir (pathname.c_str ());
+ if (dirp2)
+ {
+ struct dirent *dp2;
- if (dirp2)
+ while ((dp2 = readdir (dirp2)) != NULL)
{
- struct dirent *dp2;
-
- while ((dp2 = readdir (dirp2)) != NULL)
- {
- char buf[1000];
- ssize_t rslt;
-
- if (!isdigit (dp2->d_name[0]))
- continue;
-
- std::string fdname
- = string_printf ("%s/%s", pathname.c_str (),
- dp2->d_name);
- rslt = readlink (fdname.c_str (), buf,
- sizeof (buf) - 1);
- if (rslt >= 0)
- buf[rslt] = '\0';
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"pid\">%s</column>"
- "<column name=\"command\">%s</column>"
- "<column name=\"file descriptor\">%s</column>"
- "<column name=\"name\">%s</column>"
- "</item>",
- dp->d_name,
- command,
- dp2->d_name,
- (rslt >= 0 ? buf : dp2->d_name));
- }
-
- closedir (dirp2);
+ char buf[1000];
+ ssize_t rslt;
+
+ if (!isdigit (dp2->d_name[0]))
+ continue;
+
+ std::string fdname
+ = string_printf ("%s/%s", pathname.c_str (),
+ dp2->d_name);
+ rslt = readlink (fdname.c_str (), buf,
+ sizeof (buf) - 1);
+ if (rslt >= 0)
+ buf[rslt] = '\0';
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"pid\">%s</column>"
+ "<column name=\"command\">%s</column>"
+ "<column name=\"file descriptor\">%s</column>"
+ "<column name=\"name\">%s</column>"
+ "</item>",
+ dp->d_name,
+ command,
+ dp2->d_name,
+ (rslt >= 0 ? buf : dp2->d_name));
}
+
+ closedir (dirp2);
}
}
-
- closedir (dirp);
}
- buffer_grow_str0 (&buffer, "</osdata>\n");
- saved_buf = buffer_finish (&buffer);
- len_avail = strlen (saved_buf);
+ closedir (dirp);
}
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- saved_buf = NULL;
- len_avail = 0;
- return 0;
- }
-
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, saved_buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Returns the socket state STATE in textual form. */
@@ -1039,49 +885,19 @@ print_sockets (unsigned short family, int tcp, struct buffer *buffer)
}
}
-/* Collect data about internet sockets and write it into READBUF. */
+/* Collect data about internet sockets and write it into BUFFER. */
-static LONGEST
-linux_xfer_osdata_isockets (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_isockets (struct buffer *buffer)
{
- static const char *buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
-
- if (offset == 0)
- {
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"I sockets\">\n");
-
- print_sockets (AF_INET, 1, &buffer);
- print_sockets (AF_INET, 0, &buffer);
- print_sockets (AF_INET6, 1, &buffer);
- print_sockets (AF_INET6, 0, &buffer);
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- buf = buffer_finish (&buffer);
- len_avail = strlen (buf);
- }
+ buffer_grow_str (buffer, "<osdata type=\"I sockets\">\n");
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- buf = NULL;
- len_avail = 0;
- return 0;
- }
+ print_sockets (AF_INET, 1, buffer);
+ print_sockets (AF_INET, 0, buffer);
+ print_sockets (AF_INET6, 1, buffer);
+ print_sockets (AF_INET6, 0, buffer);
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Converts the time SECONDS into textual form and copies it into a
@@ -1120,546 +936,444 @@ group_from_gid (char *group, int maxlen, gid_t gid)
}
/* Collect data about shared memory recorded in /proc and write it
- into READBUF. */
+ into BUFFER. */
-static LONGEST
-linux_xfer_osdata_shm (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_shm (struct buffer *buffer)
{
- static const char *saved_buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ buffer_grow_str (buffer, "<osdata type=\"shared memory\">\n");
- if (offset == 0)
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
+ if (fp)
{
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- saved_buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"shared memory\">\n");
-
- gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/shm", "r");
- if (fp)
- {
- char buf[8192];
+ char buf[8192];
- do
+ do
+ {
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
- if (fgets (buf, sizeof (buf), fp.get ()))
+ key_t key;
+ uid_t uid, cuid;
+ gid_t gid, cgid;
+ PID_T cpid, lpid;
+ int shmid, size, nattch;
+ TIME_T atime, dtime, ctime;
+ unsigned int perms;
+ int items_read;
+
+ items_read = sscanf (buf,
+ "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
+ &key, &shmid, &perms, &size,
+ &cpid, &lpid,
+ &nattch,
+ &uid, &gid, &cuid, &cgid,
+ &atime, &dtime, &ctime);
+
+ if (items_read == 14)
{
- key_t key;
- uid_t uid, cuid;
- gid_t gid, cgid;
- PID_T cpid, lpid;
- int shmid, size, nattch;
- TIME_T atime, dtime, ctime;
- unsigned int perms;
- int items_read;
-
- items_read = sscanf (buf,
- "%d %d %o %d %lld %lld %d %u %u %u %u %lld %lld %lld",
- &key, &shmid, &perms, &size,
- &cpid, &lpid,
- &nattch,
- &uid, &gid, &cuid, &cgid,
- &atime, &dtime, &ctime);
-
- if (items_read == 14)
- {
- char user[UT_NAMESIZE], group[UT_NAMESIZE];
- char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
- char ccmd[32], lcmd[32];
- char atime_str[32], dtime_str[32], ctime_str[32];
-
- user_from_uid (user, sizeof (user), uid);
- group_from_gid (group, sizeof (group), gid);
- user_from_uid (cuser, sizeof (cuser), cuid);
- group_from_gid (cgroup, sizeof (cgroup), cgid);
-
- command_from_pid (ccmd, sizeof (ccmd), cpid);
- command_from_pid (lcmd, sizeof (lcmd), lpid);
-
- time_from_time_t (atime_str, sizeof (atime_str), atime);
- time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
- time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"key\">%d</column>"
- "<column name=\"shmid\">%d</column>"
- "<column name=\"permissions\">%o</column>"
- "<column name=\"size\">%d</column>"
- "<column name=\"creator command\">%s</column>"
- "<column name=\"last op. command\">%s</column>"
- "<column name=\"num attached\">%d</column>"
- "<column name=\"user\">%s</column>"
- "<column name=\"group\">%s</column>"
- "<column name=\"creator user\">%s</column>"
- "<column name=\"creator group\">%s</column>"
- "<column name=\"last shmat() time\">%s</column>"
- "<column name=\"last shmdt() time\">%s</column>"
- "<column name=\"last shmctl() time\">%s</column>"
- "</item>",
- key,
- shmid,
- perms,
- size,
- ccmd,
- lcmd,
- nattch,
- user,
- group,
- cuser,
- cgroup,
- atime_str,
- dtime_str,
- ctime_str);
- }
+ char user[UT_NAMESIZE], group[UT_NAMESIZE];
+ char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
+ char ccmd[32], lcmd[32];
+ char atime_str[32], dtime_str[32], ctime_str[32];
+
+ user_from_uid (user, sizeof (user), uid);
+ group_from_gid (group, sizeof (group), gid);
+ user_from_uid (cuser, sizeof (cuser), cuid);
+ group_from_gid (cgroup, sizeof (cgroup), cgid);
+
+ command_from_pid (ccmd, sizeof (ccmd), cpid);
+ command_from_pid (lcmd, sizeof (lcmd), lpid);
+
+ time_from_time_t (atime_str, sizeof (atime_str), atime);
+ time_from_time_t (dtime_str, sizeof (dtime_str), dtime);
+ time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"key\">%d</column>"
+ "<column name=\"shmid\">%d</column>"
+ "<column name=\"permissions\">%o</column>"
+ "<column name=\"size\">%d</column>"
+ "<column name=\"creator command\">%s</column>"
+ "<column name=\"last op. command\">%s</column>"
+ "<column name=\"num attached\">%d</column>"
+ "<column name=\"user\">%s</column>"
+ "<column name=\"group\">%s</column>"
+ "<column name=\"creator user\">%s</column>"
+ "<column name=\"creator group\">%s</column>"
+ "<column name=\"last shmat() time\">%s</column>"
+ "<column name=\"last shmdt() time\">%s</column>"
+ "<column name=\"last shmctl() time\">%s</column>"
+ "</item>",
+ key,
+ shmid,
+ perms,
+ size,
+ ccmd,
+ lcmd,
+ nattch,
+ user,
+ group,
+ cuser,
+ cgroup,
+ atime_str,
+ dtime_str,
+ ctime_str);
}
}
- while (!feof (fp.get ()));
}
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- saved_buf = buffer_finish (&buffer);
- len_avail = strlen (saved_buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- saved_buf = NULL;
- len_avail = 0;
- return 0;
+ while (!feof (fp.get ()));
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, saved_buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Collect data about semaphores recorded in /proc and write it
- into READBUF. */
+ into BUFFER. */
-static LONGEST
-linux_xfer_osdata_sem (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_sem (struct buffer *buffer)
{
- static const char *saved_buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ buffer_grow_str (buffer, "<osdata type=\"semaphores\">\n");
- if (offset == 0)
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
+ if (fp)
{
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- saved_buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"semaphores\">\n");
-
- gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/sem", "r");
- if (fp)
- {
- char buf[8192];
+ char buf[8192];
- do
+ do
+ {
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
- if (fgets (buf, sizeof (buf), fp.get ()))
+ key_t key;
+ uid_t uid, cuid;
+ gid_t gid, cgid;
+ unsigned int perms, nsems;
+ int semid;
+ TIME_T otime, ctime;
+ int items_read;
+
+ items_read = sscanf (buf,
+ "%d %d %o %u %d %d %d %d %lld %lld",
+ &key, &semid, &perms, &nsems,
+ &uid, &gid, &cuid, &cgid,
+ &otime, &ctime);
+
+ if (items_read == 10)
{
- key_t key;
- uid_t uid, cuid;
- gid_t gid, cgid;
- unsigned int perms, nsems;
- int semid;
- TIME_T otime, ctime;
- int items_read;
-
- items_read = sscanf (buf,
- "%d %d %o %u %d %d %d %d %lld %lld",
- &key, &semid, &perms, &nsems,
- &uid, &gid, &cuid, &cgid,
- &otime, &ctime);
-
- if (items_read == 10)
- {
- char user[UT_NAMESIZE], group[UT_NAMESIZE];
- char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
- char otime_str[32], ctime_str[32];
-
- user_from_uid (user, sizeof (user), uid);
- group_from_gid (group, sizeof (group), gid);
- user_from_uid (cuser, sizeof (cuser), cuid);
- group_from_gid (cgroup, sizeof (cgroup), cgid);
-
- time_from_time_t (otime_str, sizeof (otime_str), otime);
- time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"key\">%d</column>"
- "<column name=\"semid\">%d</column>"
- "<column name=\"permissions\">%o</column>"
- "<column name=\"num semaphores\">%u</column>"
- "<column name=\"user\">%s</column>"
- "<column name=\"group\">%s</column>"
- "<column name=\"creator user\">%s</column>"
- "<column name=\"creator group\">%s</column>"
- "<column name=\"last semop() time\">%s</column>"
- "<column name=\"last semctl() time\">%s</column>"
- "</item>",
- key,
- semid,
- perms,
- nsems,
- user,
- group,
- cuser,
- cgroup,
- otime_str,
- ctime_str);
- }
+ char user[UT_NAMESIZE], group[UT_NAMESIZE];
+ char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
+ char otime_str[32], ctime_str[32];
+
+ user_from_uid (user, sizeof (user), uid);
+ group_from_gid (group, sizeof (group), gid);
+ user_from_uid (cuser, sizeof (cuser), cuid);
+ group_from_gid (cgroup, sizeof (cgroup), cgid);
+
+ time_from_time_t (otime_str, sizeof (otime_str), otime);
+ time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"key\">%d</column>"
+ "<column name=\"semid\">%d</column>"
+ "<column name=\"permissions\">%o</column>"
+ "<column name=\"num semaphores\">%u</column>"
+ "<column name=\"user\">%s</column>"
+ "<column name=\"group\">%s</column>"
+ "<column name=\"creator user\">%s</column>"
+ "<column name=\"creator group\">%s</column>"
+ "<column name=\"last semop() time\">%s</column>"
+ "<column name=\"last semctl() time\">%s</column>"
+ "</item>",
+ key,
+ semid,
+ perms,
+ nsems,
+ user,
+ group,
+ cuser,
+ cgroup,
+ otime_str,
+ ctime_str);
}
}
- while (!feof (fp.get ()));
}
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- saved_buf = buffer_finish (&buffer);
- len_avail = strlen (saved_buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- saved_buf = NULL;
- len_avail = 0;
- return 0;
+ while (!feof (fp.get ()));
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, saved_buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Collect data about message queues recorded in /proc and write it
- into READBUF. */
+ into BUFFER. */
-static LONGEST
-linux_xfer_osdata_msg (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_msg (struct buffer *buffer)
{
- static const char *saved_buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ buffer_grow_str (buffer, "<osdata type=\"message queues\">\n");
- if (offset == 0)
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
+ if (fp)
{
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- saved_buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"message queues\">\n");
-
- gdb_file_up fp = gdb_fopen_cloexec ("/proc/sysvipc/msg", "r");
- if (fp)
- {
- char buf[8192];
+ char buf[8192];
- do
+ do
+ {
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
- if (fgets (buf, sizeof (buf), fp.get ()))
+ key_t key;
+ PID_T lspid, lrpid;
+ uid_t uid, cuid;
+ gid_t gid, cgid;
+ unsigned int perms, cbytes, qnum;
+ int msqid;
+ TIME_T stime, rtime, ctime;
+ int items_read;
+
+ items_read = sscanf (buf,
+ "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
+ &key, &msqid, &perms, &cbytes, &qnum,
+ &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
+ &stime, &rtime, &ctime);
+
+ if (items_read == 14)
{
- key_t key;
- PID_T lspid, lrpid;
- uid_t uid, cuid;
- gid_t gid, cgid;
- unsigned int perms, cbytes, qnum;
- int msqid;
- TIME_T stime, rtime, ctime;
- int items_read;
-
- items_read = sscanf (buf,
- "%d %d %o %u %u %lld %lld %d %d %d %d %lld %lld %lld",
- &key, &msqid, &perms, &cbytes, &qnum,
- &lspid, &lrpid, &uid, &gid, &cuid, &cgid,
- &stime, &rtime, &ctime);
-
- if (items_read == 14)
- {
- char user[UT_NAMESIZE], group[UT_NAMESIZE];
- char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
- char lscmd[32], lrcmd[32];
- char stime_str[32], rtime_str[32], ctime_str[32];
-
- user_from_uid (user, sizeof (user), uid);
- group_from_gid (group, sizeof (group), gid);
- user_from_uid (cuser, sizeof (cuser), cuid);
- group_from_gid (cgroup, sizeof (cgroup), cgid);
-
- command_from_pid (lscmd, sizeof (lscmd), lspid);
- command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
-
- time_from_time_t (stime_str, sizeof (stime_str), stime);
- time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
- time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
-
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"key\">%d</column>"
- "<column name=\"msqid\">%d</column>"
- "<column name=\"permissions\">%o</column>"
- "<column name=\"num used bytes\">%u</column>"
- "<column name=\"num messages\">%u</column>"
- "<column name=\"last msgsnd() command\">%s</column>"
- "<column name=\"last msgrcv() command\">%s</column>"
- "<column name=\"user\">%s</column>"
- "<column name=\"group\">%s</column>"
- "<column name=\"creator user\">%s</column>"
- "<column name=\"creator group\">%s</column>"
- "<column name=\"last msgsnd() time\">%s</column>"
- "<column name=\"last msgrcv() time\">%s</column>"
- "<column name=\"last msgctl() time\">%s</column>"
- "</item>",
- key,
- msqid,
- perms,
- cbytes,
- qnum,
- lscmd,
- lrcmd,
- user,
- group,
- cuser,
- cgroup,
- stime_str,
- rtime_str,
- ctime_str);
- }
+ char user[UT_NAMESIZE], group[UT_NAMESIZE];
+ char cuser[UT_NAMESIZE], cgroup[UT_NAMESIZE];
+ char lscmd[32], lrcmd[32];
+ char stime_str[32], rtime_str[32], ctime_str[32];
+
+ user_from_uid (user, sizeof (user), uid);
+ group_from_gid (group, sizeof (group), gid);
+ user_from_uid (cuser, sizeof (cuser), cuid);
+ group_from_gid (cgroup, sizeof (cgroup), cgid);
+
+ command_from_pid (lscmd, sizeof (lscmd), lspid);
+ command_from_pid (lrcmd, sizeof (lrcmd), lrpid);
+
+ time_from_time_t (stime_str, sizeof (stime_str), stime);
+ time_from_time_t (rtime_str, sizeof (rtime_str), rtime);
+ time_from_time_t (ctime_str, sizeof (ctime_str), ctime);
+
+ buffer_xml_printf
+ (buffer,
+ "<item>"
+ "<column name=\"key\">%d</column>"
+ "<column name=\"msqid\">%d</column>"
+ "<column name=\"permissions\">%o</column>"
+ "<column name=\"num used bytes\">%u</column>"
+ "<column name=\"num messages\">%u</column>"
+ "<column name=\"last msgsnd() command\">%s</column>"
+ "<column name=\"last msgrcv() command\">%s</column>"
+ "<column name=\"user\">%s</column>"
+ "<column name=\"group\">%s</column>"
+ "<column name=\"creator user\">%s</column>"
+ "<column name=\"creator group\">%s</column>"
+ "<column name=\"last msgsnd() time\">%s</column>"
+ "<column name=\"last msgrcv() time\">%s</column>"
+ "<column name=\"last msgctl() time\">%s</column>"
+ "</item>",
+ key,
+ msqid,
+ perms,
+ cbytes,
+ qnum,
+ lscmd,
+ lrcmd,
+ user,
+ group,
+ cuser,
+ cgroup,
+ stime_str,
+ rtime_str,
+ ctime_str);
}
}
- while (!feof (fp.get ()));
}
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- saved_buf = buffer_finish (&buffer);
- len_avail = strlen (saved_buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- saved_buf = NULL;
- len_avail = 0;
- return 0;
+ while (!feof (fp.get ()));
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, saved_buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
/* Collect data about loaded kernel modules and write it into
- READBUF. */
+ BUFFER. */
-static LONGEST
-linux_xfer_osdata_modules (gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+static void
+linux_xfer_osdata_modules (struct buffer *buffer)
{
- static const char *saved_buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ buffer_grow_str (buffer, "<osdata type=\"modules\">\n");
- if (offset == 0)
+ gdb_file_up fp = gdb_fopen_cloexec ("/proc/modules", "r");
+ if (fp)
{
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- saved_buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"modules\">\n");
-
- gdb_file_up fp = gdb_fopen_cloexec ("/proc/modules", "r");
- if (fp)
- {
- char buf[8192];
+ char buf[8192];
- do
+ do
+ {
+ if (fgets (buf, sizeof (buf), fp.get ()))
{
- if (fgets (buf, sizeof (buf), fp.get ()))
- {
- char *name, *dependencies, *status, *tmp;
- unsigned int size;
- unsigned long long address;
- int uses;
+ char *name, *dependencies, *status, *tmp;
+ unsigned int size;
+ unsigned long long address;
+ int uses;
- name = strtok (buf, " ");
- if (name == NULL)
- continue;
+ name = strtok (buf, " ");
+ if (name == NULL)
+ continue;
- tmp = strtok (NULL, " ");
- if (tmp == NULL)
- continue;
- if (sscanf (tmp, "%u", &size) != 1)
- continue;
+ tmp = strtok (NULL, " ");
+ if (tmp == NULL)
+ continue;
+ if (sscanf (tmp, "%u", &size) != 1)
+ continue;
- tmp = strtok (NULL, " ");
- if (tmp == NULL)
- continue;
- if (sscanf (tmp, "%d", &uses) != 1)
- continue;
+ tmp = strtok (NULL, " ");
+ if (tmp == NULL)
+ continue;
+ if (sscanf (tmp, "%d", &uses) != 1)
+ continue;
- dependencies = strtok (NULL, " ");
- if (dependencies == NULL)
- continue;
+ dependencies = strtok (NULL, " ");
+ if (dependencies == NULL)
+ continue;
- status = strtok (NULL, " ");
- if (status == NULL)
- continue;
+ status = strtok (NULL, " ");
+ if (status == NULL)
+ continue;
- tmp = strtok (NULL, "\n");
- if (tmp == NULL)
- continue;
- if (sscanf (tmp, "%llx", &address) != 1)
- continue;
+ tmp = strtok (NULL, "\n");
+ if (tmp == NULL)
+ continue;
+ if (sscanf (tmp, "%llx", &address) != 1)
+ continue;
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"name\">%s</column>"
- "<column name=\"size\">%u</column>"
- "<column name=\"num uses\">%d</column>"
- "<column name=\"dependencies\">%s</column>"
- "<column name=\"status\">%s</column>"
- "<column name=\"address\">%llx</column>"
- "</item>",
- name,
- size,
- uses,
- dependencies,
- status,
- address);
- }
+ buffer_xml_printf (buffer,
+ "<item>"
+ "<column name=\"name\">%s</column>"
+ "<column name=\"size\">%u</column>"
+ "<column name=\"num uses\">%d</column>"
+ "<column name=\"dependencies\">%s</column>"
+ "<column name=\"status\">%s</column>"
+ "<column name=\"address\">%llx</column>"
+ "</item>",
+ name,
+ size,
+ uses,
+ dependencies,
+ status,
+ address);
}
- while (!feof (fp.get ()));
}
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- saved_buf = buffer_finish (&buffer);
- len_avail = strlen (saved_buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- saved_buf = NULL;
- len_avail = 0;
- return 0;
+ while (!feof (fp.get ()));
}
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, saved_buf + offset, len);
-
- return len;
+ buffer_grow_str0 (buffer, "</osdata>\n");
}
+static void
+linux_xfer_osdata_info_os_types (struct buffer *buffer);
+
struct osdata_type {
const char *type;
const char *title;
const char *description;
- LONGEST (*getter) (gdb_byte *readbuf, ULONGEST offset, ULONGEST len);
+ void (*take_snapshot) (struct buffer *buffer);
+ LONGEST len_avail;
+ struct buffer buffer;
} osdata_table[] = {
+ { "types", "Types", "Listing of info os types you can list",
+ linux_xfer_osdata_info_os_types, -1 },
{ "cpus", "CPUs", "Listing of all cpus/cores on the system",
- linux_xfer_osdata_cpus },
+ linux_xfer_osdata_cpus, -1 },
{ "files", "File descriptors", "Listing of all file descriptors",
- linux_xfer_osdata_fds },
+ linux_xfer_osdata_fds, -1 },
{ "modules", "Kernel modules", "Listing of all loaded kernel modules",
- linux_xfer_osdata_modules },
+ linux_xfer_osdata_modules, -1 },
{ "msg", "Message queues", "Listing of all message queues",
- linux_xfer_osdata_msg },
+ linux_xfer_osdata_msg, -1 },
{ "processes", "Processes", "Listing of all processes",
- linux_xfer_osdata_processes },
+ linux_xfer_osdata_processes, -1 },
{ "procgroups", "Process groups", "Listing of all process groups",
- linux_xfer_osdata_processgroups },
+ linux_xfer_osdata_processgroups, -1 },
{ "semaphores", "Semaphores", "Listing of all semaphores",
- linux_xfer_osdata_sem },
+ linux_xfer_osdata_sem, -1 },
{ "shm", "Shared-memory regions", "Listing of all shared-memory regions",
- linux_xfer_osdata_shm },
+ linux_xfer_osdata_shm, -1 },
{ "sockets", "Sockets", "Listing of all internet-domain sockets",
- linux_xfer_osdata_isockets },
+ linux_xfer_osdata_isockets, -1 },
{ "threads", "Threads", "Listing of all threads",
- linux_xfer_osdata_threads },
+ linux_xfer_osdata_threads, -1 },
{ NULL, NULL, NULL }
};
-LONGEST
-linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
- ULONGEST offset, ULONGEST len)
+/* Collect data about all types info os can show in BUFFER. */
+
+static void
+linux_xfer_osdata_info_os_types (struct buffer *buffer)
{
- if (!annex || *annex == '\0')
- {
- static const char *buf;
- static LONGEST len_avail = -1;
- static struct buffer buffer;
+ buffer_grow_str (buffer, "<osdata type=\"types\">\n");
+
+ /* Start the below loop at 1, as we do not want to list ourselves. */
+ for (int i = 1; osdata_table[i].type; ++i)
+ buffer_xml_printf (buffer,
+ "<item>"
+ "<column name=\"Type\">%s</column>"
+ "<column name=\"Description\">%s</column>"
+ "<column name=\"Title\">%s</column>"
+ "</item>",
+ osdata_table[i].type,
+ osdata_table[i].description,
+ osdata_table[i].title);
+
+ buffer_grow_str0 (buffer, "</osdata>\n");
+}
- if (offset == 0)
- {
- int i;
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- buf = NULL;
- buffer_init (&buffer);
- buffer_grow_str (&buffer, "<osdata type=\"types\">\n");
-
- for (i = 0; osdata_table[i].type; ++i)
- buffer_xml_printf (
- &buffer,
- "<item>"
- "<column name=\"Type\">%s</column>"
- "<column name=\"Description\">%s</column>"
- "<column name=\"Title\">%s</column>"
- "</item>",
- osdata_table[i].type,
- osdata_table[i].description,
- osdata_table[i].title);
-
- buffer_grow_str0 (&buffer, "</osdata>\n");
- buf = buffer_finish (&buffer);
- len_avail = strlen (buf);
- }
+/* Copies up to LEN bytes in READBUF from offset OFFSET in OSD->BUFFER.
+ If OFFSET is zero, first calls OSD->TAKE_SNAPSHOT. */
- if (offset >= len_avail)
- {
- /* Done. Get rid of the buffer. */
- buffer_free (&buffer);
- buf = NULL;
- len_avail = 0;
- return 0;
- }
+static LONGEST
+common_getter (struct osdata_type *osd,
+ gdb_byte *readbuf, ULONGEST offset, ULONGEST len)
+{
+ gdb_assert (readbuf);
+
+ if (offset == 0)
+ {
+ if (osd->len_avail != -1 && osd->len_avail != 0)
+ buffer_free (&osd->buffer);
+ osd->len_avail = 0;
+ buffer_init (&osd->buffer);
+ (osd->take_snapshot) (&osd->buffer);
+ osd->len_avail = strlen (osd->buffer.buffer);
+ }
+ if (offset >= osd->len_avail)
+ {
+ /* Done. Get rid of the buffer. */
+ buffer_free (&osd->buffer);
+ osd->len_avail = 0;
+ return 0;
+ }
+ if (len > osd->len_avail - offset)
+ len = osd->len_avail - offset;
+ memcpy (readbuf, osd->buffer.buffer + offset, len);
- if (len > len_avail - offset)
- len = len_avail - offset;
- memcpy (readbuf, buf + offset, len);
+ return len;
+
+}
- return len;
+LONGEST
+linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
+ ULONGEST offset, ULONGEST len)
+{
+ if (!annex || *annex == '\0')
+ {
+ return common_getter (&osdata_table[0],
+ readbuf, offset, len);
}
else
{
@@ -1668,11 +1382,8 @@ linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
for (i = 0; osdata_table[i].type; ++i)
{
if (strcmp (annex, osdata_table[i].type) == 0)
- {
- gdb_assert (readbuf);
-
- return (osdata_table[i].getter) (readbuf, offset, len);
- }
+ return common_getter (&osdata_table[i],
+ readbuf, offset, len);
}
return 0;