aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver/linux-low.c
diff options
context:
space:
mode:
authorKwok Yeung <kcy@sourceware.org>2011-07-21 23:46:12 +0000
committerKwok Yeung <kcy@sourceware.org>2011-07-21 23:46:12 +0000
commitd26e3629bbf1122feb8400bdeb8da32931c24d61 (patch)
treeaeb70412b9df767983a9ff2e99a05537ad96e18e /gdb/gdbserver/linux-low.c
parentedc849905405c3c77b7655f669f874e8b0d227e0 (diff)
downloadgdb-d26e3629bbf1122feb8400bdeb8da32931c24d61.zip
gdb-d26e3629bbf1122feb8400bdeb8da32931c24d61.tar.gz
gdb-d26e3629bbf1122feb8400bdeb8da32931c24d61.tar.bz2
2011-07-22 Kwok Cheung Yeung <kcy@codesourcery.com>
gdb/ * defs.h: Add guard against inclusion in gdbserver. (struct ptid, ptid_t): Move to common/ptid.h. (xfree, xzalloc, xasprintf, xvasprintf, xstrprintf, xstrvprintf, xsnprintf, internal_error): Move to common/common-utils.h. (nomem): Delete. * gdb_assert.h: Move into common/ sub-directory. * gdb_locale.h: Ditto. * gdb_dirent.h: Ditto. * inferior.h (minus_one_ptid, null_ptid, ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid): Move into common/ptid.h. * xml-support.c (xml_escape_text): Move into common/xml-utils.c. (gdb_xml_create_parser_and_cleanup_1, xml_fetch_context_from_file): Change nomem to malloc_failure. * xml-support.h (xml_escape_text): Move into common/xml-utils.h. * utils.c (nomem): Rename to malloc_failure. (xmalloc, xzalloc, xrealloc, xcalloc, xfree, xstrprintf, xasprintf, xvasprintf, xstrvprintf, xsnprintf): Move to common/common-utils.c. (gdb_buildargv): Change nomem to malloc_failure. * infrun.c (null_ptid, minus_one_ptid, ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid): Move into common/ptid.c. (initialize_infrun): Delete initialization of null_ptid and minus_one_ptid. * linux-nat.c (linux_nat_xfer_osdata): Defer to linux_common_xfer_osdata. * Makefile.in (SFILES): Add common/common-utils.c, common/xml-utils.c, common/ptid.c and common/buffer.c. (HFILES_NO_SRCDIR): Add common/common-utils.h, common/xml-utils.h, common/ptid.h, common/buffer.h and common/linux-osdata.h. (COMMON_OBS): Add xml-utils.o, common-utils.o, buffer.o and ptid.o. (common-utils.o, xml-utils.o, ptid.o, buffer.o, linux-osdata.o): New rules. * common/gdb_assert.h: New. * common/gdb_dirent.h: New. * common/gdb_locale.h: New. * common/buffer.c: New. * common/buffer.h: New. * common/ptid.c: New. * common/ptid.h: New. * common/xml-utils.c: New. * common/xml-utils.h: New. * common/common-utils.c: New. * common/common-utils.h: New. * common/linux-osdata.c: New. * common/linux-osdata.h: New. * config/alpha/alpha-linux.mh (NATDEPFILES): Add linux-osdata.o. * config/arm/linux.mh (NATDEPFILES): Ditto. * config/i386/linux.mh (NATDEPFILES): Ditto. * config/i386/linux64.mh (NATDEPFILES): Ditto. * config/ia64/linux.mh (NATDEPFILES): Ditto. * config/m32r/linux.mh (NATDEPFILES): Ditto. * config/m68k/linux.mh (NATDEPFILES): Ditto. * config/mips/linux.mh (NATDEPFILES): Ditto. * config/pa/linux.mh (NATDEPFILES): Ditto. * config/powerpc/linux.mh (NATDEPFILES): Ditto. * config/powerpc/ppc64-linux.mh (NATDEPFILES): Ditto. * config/s390/s390.mh (NATDEPFILES): Ditto. * config/sparc/linux.mh (NATDEPFILES): Ditto. * config/sparc/linux64.mh (NATDEPFILES): Ditto. * config/xtensa/linux.mh (NATDEPFILES): Ditto. gdbserver/ * linux-low.c (compare_ints, unique, list_threads, show_process, linux_core_of_thread): Delete. (linux_target_ops): Change linux_core_of_thread to linux_common_core_of_thread. (linux_qxfer_osdata): Defer to linux_common_xfer_osdata. * utils.c (malloc_failure): Change type of argument. (xmalloc, xrealloc, xcalloc, xsnprintf): Delete. * Makefile.in (SFILES): Add common/common-utils.c, common/xml-utils.c, common/linux-osdata.c, common/ptid.c and common/buffer.c. (OBS): Add xml-utils.o, common-utils.o, ptid.o and buffer.o. (IPA_OBJS): Add common-utils-ipa.o. (ptid_h, linux_osdata_h): New macros. (server_h): Add common/common-utils.h, common/xml-utils.h, common/buffer.h, common/gdb_assert.h, common/gdb_locale.h and common/ptid.h. (common-utils-ipa.o, common-utils.o, xml-utils.o, linux-osdata.o, ptid.o, buffer.o): New rules. (linux-low.o): Add common/linux-osdata.h as a dependency. * configure.srv (srv_tgtobj): Add linux-osdata.o to Linux targets. * configure.ac: Add AC_HEADER_DIRENT check. * config.in: Regenerate. * configure: Regenerate. * remote-utils.c (xml_escape_text): Delete. (buffer_grow, buffer_free, buffer_init, buffer_finish, buffer_xml_printf): Move to common/buffer.c. * server.c (main): Remove call to initialize_inferiors. * server.h (struct ptid, ptid_t, minus_one_ptid, null_ptid, ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid, initialize_inferiors, xml_escape_text, internal_error, gdb_assert, gdb_assert_fail): Delete. (struct buffer, buffer_grow, buffer_free, buffer_init, buffer_finish, buffer_xml_printf, buffer_grow_str, buffer_grow_str0): Move to common/buffer.h. * inferiors.c (null_ptid, minus_one_ptid, ptid_build, pid_to_ptid, ptid_get_pid, ptid_get_lwp, ptid_get_tid, ptid_equal, ptid_is_pid, initialize_inferiors): Delete.
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,