Use std::vector in linux_xfer_osdata_processgroups

This simplifies the code quite a bit, by removing the array of PID_T
that's actually an array of pairs of PID_T.

This code is only used to implement "info os procgroups".  I tested by hand
as well as by running gdb.base/info-os.exp for unix, native-gdbserver
and native-extended-gdbserver.

gdb/ChangeLog:

	* nat/linux-osdata.c: Include algorithm.
	(compare_processes): Remove.
	(struct pid_pgid_entry): New struct.
	(linux_xfer_osdata_processgroups): Use std::vector instead of
	XNEWVEC.
This commit is contained in:
Simon Marchi
2017-10-14 08:38:02 -04:00
parent af5bf4ada4
commit b129dcac88
2 changed files with 48 additions and 56 deletions

View File

@ -1,3 +1,11 @@
2017-10-14 Simon Marchi <simon.marchi@ericsson.com>
* nat/linux-osdata.c: Include algorithm.
(compare_processes): Remove.
(struct pid_pgid_entry): New struct.
(linux_xfer_osdata_processgroups): Use std::vector instead of
XNEWVEC.
2017-10-14 Simon Marchi <simon.marchi@ericsson.com> 2017-10-14 Simon Marchi <simon.marchi@ericsson.com>
* objfiles.h: Don't include symfile.h. * objfiles.h: Don't include symfile.h.

View File

@ -37,6 +37,7 @@
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include "filestuff.h" #include "filestuff.h"
#include <algorithm>
#define NAMELEN(dirent) strlen ((dirent)->d_name) #define NAMELEN(dirent) strlen ((dirent)->d_name)
@ -391,41 +392,40 @@ linux_xfer_osdata_processes (gdb_byte *readbuf,
return len; return len;
} }
/* Auxiliary function used by qsort to sort processes by process /* A simple PID/PGID pair. */
group. Compares two processes with ids PROCESS1 and PROCESS2.
PROCESS1 comes before PROCESS2 if it has a lower process group id.
If they belong to the same process group, PROCESS1 comes before
PROCESS2 if it has a lower process id or is the process group
leader. */
static int struct pid_pgid_entry
compare_processes (const void *process1, const void *process2)
{ {
PID_T pid1 = *((PID_T *) process1); pid_pgid_entry (PID_T pid_, PID_T pgid_)
PID_T pid2 = *((PID_T *) process2); : pid (pid_), pgid (pgid_)
PID_T pgid1 = *((PID_T *) process1 + 1); {}
PID_T pgid2 = *((PID_T *) process2 + 1);
/* Sort by PGID. */ /* Return true if this pid is the leader of its process group. */
if (pgid1 < pgid2)
return -1; bool is_leader () const
else if (pgid1 > pgid2) {
return 1; return pid == pgid;
else }
{
/* Process group leaders always come first, else sort by PID. */ bool operator< (const pid_pgid_entry &other)
if (pid1 == pgid1) {
return -1; /* Sort by PGID. */
else if (pid2 == pgid2) if (this->pgid != other.pgid)
return 1; return this->pgid < other.pgid;
else if (pid1 < pid2)
return -1; /* Process group leaders always come first... */
else if (pid1 > pid2) if (this->is_leader ())
return 1; return true;
else
return 0; if (other.is_leader ())
} return false;
}
/* ...else sort by PID. */
return this->pid < other.pid;
}
PID_T pid, pgid;
};
/* Collect all process groups from /proc. */ /* Collect all process groups from /proc. */
@ -452,11 +452,10 @@ linux_xfer_osdata_processgroups (gdb_byte *readbuf,
dirp = opendir ("/proc"); dirp = opendir ("/proc");
if (dirp) if (dirp)
{ {
std::vector<pid_pgid_entry> process_list;
struct dirent *dp; struct dirent *dp;
const size_t list_block_size = 512;
PID_T *process_list = XNEWVEC (PID_T, list_block_size * 2); process_list.reserve (512);
size_t process_count = 0;
size_t i;
/* Build list consisting of PIDs followed by their /* Build list consisting of PIDs followed by their
associated PGID. */ associated PGID. */
@ -472,30 +471,18 @@ linux_xfer_osdata_processgroups (gdb_byte *readbuf,
pgid = getpgid (pid); pgid = getpgid (pid);
if (pgid > 0) if (pgid > 0)
{ process_list.emplace_back (pid, pgid);
process_list[2 * process_count] = pid;
process_list[2 * process_count + 1] = pgid;
++process_count;
/* Increase the size of the list if necessary. */
if (process_count % list_block_size == 0)
process_list = (PID_T *) xrealloc (
process_list,
(process_count + list_block_size)
* 2 * sizeof (PID_T));
}
} }
closedir (dirp); closedir (dirp);
/* Sort the process list. */ /* Sort the process list. */
qsort (process_list, process_count, 2 * sizeof (PID_T), std::sort (process_list.begin (), process_list.end ());
compare_processes);
for (i = 0; i < process_count; ++i) for (const pid_pgid_entry &entry : process_list)
{ {
PID_T pid = process_list[2 * i]; PID_T pid = entry.pid;
PID_T pgid = process_list[2 * i + 1]; PID_T pgid = entry.pgid;
char leader_command[32]; char leader_command[32];
char *command_line; char *command_line;
@ -517,8 +504,6 @@ linux_xfer_osdata_processgroups (gdb_byte *readbuf,
xfree (command_line); xfree (command_line);
} }
xfree (process_list);
} }
buffer_grow_str0 (&buffer, "</osdata>\n"); buffer_grow_str0 (&buffer, "</osdata>\n");
@ -1697,4 +1682,3 @@ linux_common_xfer_osdata (const char *annex, gdb_byte *readbuf,
return 0; return 0;
} }
} }