diff options
author | Kwok Yeung <kcy@sourceware.org> | 2011-07-21 23:46:12 +0000 |
---|---|---|
committer | Kwok Yeung <kcy@sourceware.org> | 2011-07-21 23:46:12 +0000 |
commit | d26e3629bbf1122feb8400bdeb8da32931c24d61 (patch) | |
tree | aeb70412b9df767983a9ff2e99a05537ad96e18e /gdb/gdbserver/linux-low.c | |
parent | edc849905405c3c77b7655f669f874e8b0d227e0 (diff) | |
download | gdb-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.c | 316 |
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, |