aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-low.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/gdbserver/linux-low.c')
-rw-r--r--gdb/gdbserver/linux-low.c316
1 files changed, 3 insertions, 313 deletions
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index d84fd68..a9cdaca 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -19,6 +19,7 @@
#include "server.h"
#include "linux-low.h"
+#include "linux-osdata.h"
#include <sys/wait.h>
#include <stdio.h>
@@ -118,7 +119,6 @@ static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
static void *add_lwp (ptid_t ptid);
static int linux_stopped_by_watchpoint (void);
static void mark_lwp_dead (struct lwp_info *lwp, int wstat);
-static int linux_core_of_thread (ptid_t ptid);
static void proceed_all_lwps (void);
static int finish_step_over (struct lwp_info *lwp);
static CORE_ADDR get_stop_pc (struct lwp_info *lwp);
@@ -4387,264 +4387,11 @@ linux_read_offsets (CORE_ADDR *text_p, CORE_ADDR *data_p)
#endif
static int
-compare_ints (const void *xa, const void *xb)
-{
- int a = *(const int *)xa;
- int b = *(const int *)xb;
-
- return a - b;
-}
-
-static int *
-unique (int *b, int *e)
-{
- int *d = b;
- while (++b != e)
- if (*d != *b)
- *++d = *b;
- return ++d;
-}
-
-/* Given PID, iterates over all threads in that process.
-
- Information about each thread, in a format suitable for qXfer:osdata:thread
- is printed to BUFFER, if it's not NULL. BUFFER is assumed to be already
- initialized, and the caller is responsible for finishing and appending '\0'
- to it.
-
- The list of cores that threads are running on is assigned to *CORES, if it
- is not NULL. If no cores are found, *CORES will be set to NULL. Caller
- should free *CORES. */
-
-static void
-list_threads (int pid, struct buffer *buffer, char **cores)
-{
- int count = 0;
- int allocated = 10;
- int *core_numbers = xmalloc (sizeof (int) * allocated);
- char pathname[128];
- DIR *dir;
- struct dirent *dp;
- struct stat statbuf;
-
- sprintf (pathname, "/proc/%d/task", pid);
- if (stat (pathname, &statbuf) == 0 && S_ISDIR (statbuf.st_mode))
- {
- dir = opendir (pathname);
- if (!dir)
- {
- free (core_numbers);
- return;
- }
-
- while ((dp = readdir (dir)) != NULL)
- {
- unsigned long lwp = strtoul (dp->d_name, NULL, 10);
-
- if (lwp != 0)
- {
- unsigned core = linux_core_of_thread (ptid_build (pid, lwp, 0));
-
- if (core != -1)
- {
- char s[sizeof ("4294967295")];
- sprintf (s, "%u", core);
-
- if (count == allocated)
- {
- allocated *= 2;
- core_numbers = realloc (core_numbers,
- sizeof (int) * allocated);
- }
- core_numbers[count++] = core;
- if (buffer)
- buffer_xml_printf (buffer,
- "<item>"
- "<column name=\"pid\">%d</column>"
- "<column name=\"tid\">%s</column>"
- "<column name=\"core\">%s</column>"
- "</item>", pid, dp->d_name, s);
- }
- else
- {
- if (buffer)
- buffer_xml_printf (buffer,
- "<item>"
- "<column name=\"pid\">%d</column>"
- "<column name=\"tid\">%s</column>"
- "</item>", pid, dp->d_name);
- }
- }
- }
- closedir (dir);
- }
-
- if (cores)
- {
- *cores = NULL;
- if (count > 0)
- {
- struct buffer buffer2;
- int *b;
- int *e;
- qsort (core_numbers, count, sizeof (int), compare_ints);
-
- /* Remove duplicates. */
- b = core_numbers;
- e = unique (b, core_numbers + count);
-
- buffer_init (&buffer2);
-
- for (b = core_numbers; b != e; ++b)
- {
- char number[sizeof ("4294967295")];
- sprintf (number, "%u", *b);
- buffer_xml_printf (&buffer2, "%s%s",
- (b == core_numbers) ? "" : ",", number);
- }
- buffer_grow_str0 (&buffer2, "");
-
- *cores = buffer_finish (&buffer2);
- }
- }
- free (core_numbers);
-}
-
-static void
-show_process (int pid, const char *username, struct buffer *buffer)
-{
- char pathname[128];
- FILE *f;
- char cmd[MAXPATHLEN + 1];
-
- sprintf (pathname, "/proc/%d/cmdline", pid);
-
- if ((f = fopen (pathname, "r")) != NULL)
- {
- size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
- if (len > 0)
- {
- char *cores = 0;
- int i;
- for (i = 0; i < len; i++)
- if (cmd[i] == '\0')
- cmd[i] = ' ';
- cmd[len] = '\0';
-
- buffer_xml_printf (buffer,
- "<item>"
- "<column name=\"pid\">%d</column>"
- "<column name=\"user\">%s</column>"
- "<column name=\"command\">%s</column>",
- pid,
- username,
- cmd);
-
- /* This only collects core numbers, and does not print threads. */
- list_threads (pid, NULL, &cores);
-
- if (cores)
- {
- buffer_xml_printf (buffer,
- "<column name=\"cores\">%s</column>", cores);
- free (cores);
- }
-
- buffer_xml_printf (buffer, "</item>");
- }
- fclose (f);
- }
-}
-
-static int
linux_qxfer_osdata (const char *annex,
unsigned char *readbuf, unsigned const char *writebuf,
CORE_ADDR offset, int len)
{
- /* We make the process list snapshot when the object starts to be
- read. */
- static const char *buf;
- static long len_avail = -1;
- static struct buffer buffer;
- int processes = 0;
- int threads = 0;
-
- DIR *dirp;
-
- if (strcmp (annex, "processes") == 0)
- processes = 1;
- else if (strcmp (annex, "threads") == 0)
- threads = 1;
- else
- return 0;
-
- if (!readbuf || writebuf)
- return 0;
-
- if (offset == 0)
- {
- if (len_avail != -1 && len_avail != 0)
- buffer_free (&buffer);
- len_avail = 0;
- buf = NULL;
- buffer_init (&buffer);
- if (processes)
- buffer_grow_str (&buffer, "<osdata type=\"processes\">");
- else if (threads)
- buffer_grow_str (&buffer, "<osdata type=\"threads\">");
-
- dirp = opendir ("/proc");
- if (dirp)
- {
- struct dirent *dp;
- while ((dp = readdir (dirp)) != NULL)
- {
- struct stat statbuf;
- char procentry[sizeof ("/proc/4294967295")];
-
- if (!isdigit (dp->d_name[0])
- || strlen (dp->d_name) > sizeof ("4294967295") - 1)
- continue;
-
- sprintf (procentry, "/proc/%s", dp->d_name);
- if (stat (procentry, &statbuf) == 0
- && S_ISDIR (statbuf.st_mode))
- {
- int pid = (int) strtoul (dp->d_name, NULL, 10);
-
- if (processes)
- {
- struct passwd *entry = getpwuid (statbuf.st_uid);
- show_process (pid, entry ? entry->pw_name : "?", &buffer);
- }
- else if (threads)
- {
- list_threads (pid, &buffer, NULL);
- }
- }
- }
-
- closedir (dirp);
- }
- buffer_grow_str0 (&buffer, "</osdata>\n");
- buf = buffer_finish (&buffer);
- len_avail = strlen (buf);
- }
-
- if (offset >= len_avail)
- {
- /* Done. Get rid of the data. */
- 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;
+ return linux_common_xfer_osdata (annex, readbuf, offset, len);
}
/* Convert a native/host siginfo object, into/from the siginfo in the
@@ -4907,63 +4654,6 @@ linux_qxfer_spu (const char *annex, unsigned char *readbuf,
return ret;
}
-static int
-linux_core_of_thread (ptid_t ptid)
-{
- char filename[sizeof ("/proc//task//stat")
- + 2 * 20 /* decimal digits for 2 numbers, max 2^64 bit each */
- + 1];
- FILE *f;
- char *content = NULL;
- char *p;
- char *ts = 0;
- int content_read = 0;
- int i;
- int core;
-
- sprintf (filename, "/proc/%d/task/%ld/stat",
- ptid_get_pid (ptid), ptid_get_lwp (ptid));
- f = fopen (filename, "r");
- if (!f)
- return -1;
-
- for (;;)
- {
- int n;
- content = realloc (content, content_read + 1024);
- n = fread (content + content_read, 1, 1024, f);
- content_read += n;
- if (n < 1024)
- {
- content[content_read] = '\0';
- break;
- }
- }
-
- p = strchr (content, '(');
-
- /* Skip ")". */
- if (p != NULL)
- p = strchr (p, ')');
- if (p != NULL)
- p++;
-
- /* If the first field after program name has index 0, then core number is
- the field with index 36. There's no constant for that anywhere. */
- if (p != NULL)
- p = strtok_r (p, " ", &ts);
- for (i = 0; p != NULL && i != 36; ++i)
- p = strtok_r (NULL, " ", &ts);
-
- if (p == NULL || sscanf (p, "%d", &core) == 0)
- core = -1;
-
- free (content);
- fclose (f);
-
- return core;
-}
-
static void
linux_process_qsupported (const char *query)
{
@@ -5111,7 +4801,7 @@ static struct target_ops linux_target_ops = {
#else
NULL,
#endif
- linux_core_of_thread,
+ linux_common_core_of_thread,
linux_process_qsupported,
linux_supports_tracepoints,
linux_read_pc,