X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Flinux-nat.c;h=93adfcd4e0df2c87927dd0b6f73be81c84ea3277;hb=91158a569dc571a9916dfad98c6c95ce789ad18d;hp=2c791dcdfe6e3c566a4fa8122af100e83ecb3c0a;hpb=75083f7e9a4f58849393d486bb24018ca030a1a6;p=binutils-gdb.git
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 2c791dcdfe6..93adfcd4e0d 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -368,6 +368,7 @@ static void
add_to_pid_list (struct simple_pid_list **listp, int pid, int status)
{
struct simple_pid_list *new_pid = xmalloc (sizeof (struct simple_pid_list));
+
new_pid->pid = pid;
new_pid->status = status;
new_pid->next = *listp;
@@ -383,6 +384,7 @@ pull_pid_from_list (struct simple_pid_list **listp, int pid, int *status)
if ((*p)->pid == pid)
{
struct simple_pid_list *next = (*p)->next;
+
*status = (*p)->status;
xfree (*p);
*p = next;
@@ -677,7 +679,7 @@ linux_child_follow_fork (struct target_ops *ops, int follow_child)
in the foreground, the user will not be able to ctrl-c to get
back the terminal, effectively hanging the debug session. */
fprintf_filtered (gdb_stderr, _("\
-Can not resume the parent process over vfork in the foreground while \n\
+Can not resume the parent process over vfork in the foreground while\n\
holding the child stopped. Try \"set detach-on-fork\" or \
\"set schedule-multiple\".\n"));
return 1;
@@ -1646,6 +1648,7 @@ get_pending_status (struct lwp_info *lp, int *status)
else if (non_stop && !is_executing (lp->ptid))
{
struct thread_info *tp = find_thread_ptid (lp->ptid);
+
signo = tp->stop_signal;
}
else if (!non_stop)
@@ -1658,6 +1661,7 @@ get_pending_status (struct lwp_info *lp, int *status)
if (GET_LWP (lp->ptid) == GET_LWP (last_ptid))
{
struct thread_info *tp = find_thread_ptid (lp->ptid);
+
signo = tp->stop_signal;
}
}
@@ -3622,7 +3626,13 @@ retry:
fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
restore_child_signals_mask (&prev_mask);
- lp->core = linux_nat_core_of_thread_1 (lp->ptid);
+
+ if (ourstatus->kind == TARGET_WAITKIND_EXITED
+ || ourstatus->kind == TARGET_WAITKIND_SIGNALLED)
+ lp->core = -1;
+ else
+ lp->core = linux_nat_core_of_thread_1 (lp->ptid);
+
return lp->ptid;
}
@@ -3802,6 +3812,7 @@ linux_nat_kill (struct target_ops *ops)
else
{
ptid_t ptid = pid_to_ptid (ptid_get_pid (inferior_ptid));
+
/* Stop all threads before killing them, since ptrace requires
that the thread is stopped to sucessfully PTRACE_KILL. */
iterate_over_lwps (ptid, stop_callback, NULL);
@@ -4123,8 +4134,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
char *note_data, int *note_size,
enum target_signal stop_signal)
{
- gdb_gregset_t gregs;
- gdb_fpregset_t fpregs;
unsigned long lwp = ptid_get_lwp (ptid);
struct gdbarch *gdbarch = target_gdbarch;
struct regcache *regcache = get_thread_arch_regcache (ptid, gdbarch);
@@ -4142,21 +4151,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
sect_list = gdbarch_core_regset_sections (gdbarch);
- if (core_regset_p
- && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
- sizeof (gregs))) != NULL
- && regset->collect_regset != NULL)
- regset->collect_regset (regset, regcache, -1,
- &gregs, sizeof (gregs));
- else
- fill_gregset (regcache, &gregs, -1);
-
- note_data = (char *) elfcore_write_prstatus (obfd,
- note_data,
- note_size,
- lwp,
- stop_signal, &gregs);
-
/* The loop below uses the new struct core_regset_section, which stores
the supported section names and sizes for the core file. Note that
note PRSTATUS needs to be treated specially. But the other notes are
@@ -4164,12 +4158,6 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
if (core_regset_p && sect_list != NULL)
while (sect_list->sect_name != NULL)
{
- /* .reg was already handled above. */
- if (strcmp (sect_list->sect_name, ".reg") == 0)
- {
- sect_list++;
- continue;
- }
regset = gdbarch_regset_from_core_section (gdbarch,
sect_list->sect_name,
sect_list->size);
@@ -4177,12 +4165,16 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
gdb_regset = xmalloc (sect_list->size);
regset->collect_regset (regset, regcache, -1,
gdb_regset, sect_list->size);
- note_data = (char *) elfcore_write_register_note (obfd,
- note_data,
- note_size,
- sect_list->sect_name,
- gdb_regset,
- sect_list->size);
+
+ if (strcmp (sect_list->sect_name, ".reg") == 0)
+ note_data = (char *) elfcore_write_prstatus
+ (obfd, note_data, note_size,
+ lwp, stop_signal, gdb_regset);
+ else
+ note_data = (char *) elfcore_write_register_note
+ (obfd, note_data, note_size,
+ sect_list->sect_name, gdb_regset,
+ sect_list->size);
xfree (gdb_regset);
sect_list++;
}
@@ -4192,6 +4184,24 @@ linux_nat_do_thread_registers (bfd *obfd, ptid_t ptid,
the new support, the code below should be deleted. */
else
{
+ gdb_gregset_t gregs;
+ gdb_fpregset_t fpregs;
+
+ if (core_regset_p
+ && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+ sizeof (gregs))) != NULL
+ && regset->collect_regset != NULL)
+ regset->collect_regset (regset, regcache, -1,
+ &gregs, sizeof (gregs));
+ else
+ fill_gregset (regcache, &gregs, -1);
+
+ note_data = (char *) elfcore_write_prstatus (obfd,
+ note_data,
+ note_size,
+ lwp,
+ stop_signal, &gregs);
+
if (core_regset_p
&& (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
sizeof (fpregs))) != NULL
@@ -4340,6 +4350,7 @@ static char *
linux_spu_make_corefile_notes (bfd *obfd, char *note_data, int *note_size)
{
struct linux_spu_corefile_data args;
+
args.obfd = obfd;
args.note_data = note_data;
args.note_size = note_size;
@@ -4496,6 +4507,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
if ((procfile = fopen (fname1, "r")) != NULL)
{
struct cleanup *cleanup = make_cleanup_fclose (procfile);
+
if (fgets (buffer, sizeof (buffer), procfile))
printf_filtered ("cmdline = '%s'\n", buffer);
else
@@ -4591,6 +4603,7 @@ linux_nat_info_proc_cmd (char *args, int from_tty)
if ((procfile = fopen (fname1, "r")) != NULL)
{
struct cleanup *cleanup = make_cleanup_fclose (procfile);
+
while (fgets (buffer, sizeof (buffer), procfile) != NULL)
puts_filtered (buffer);
do_cleanups (cleanup);
@@ -4921,8 +4934,8 @@ linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigse
static LONGEST
linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
+ const char *annex, gdb_byte *readbuf,
+ const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
/* We make the process list snapshot when the object starts to be
read. */
@@ -4934,6 +4947,45 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
gdb_assert (object == TARGET_OBJECT_OSDATA);
+ if (!annex)
+ {
+ if (offset == 0)
+ {
+ if (len_avail != -1 && len_avail != 0)
+ obstack_free (&obstack, NULL);
+ len_avail = 0;
+ buf = NULL;
+ obstack_init (&obstack);
+ obstack_grow_str (&obstack, "\n");
+
+ obstack_xml_printf (
+ &obstack,
+ "- "
+ "processes"
+ "Listing of all processes"
+ "
");
+
+ obstack_grow_str0 (&obstack, "\n");
+ buf = obstack_finish (&obstack);
+ len_avail = strlen (buf);
+ }
+
+ if (offset >= len_avail)
+ {
+ /* Done. Get rid of the obstack. */
+ obstack_free (&obstack, NULL);
+ buf = NULL;
+ len_avail = 0;
+ return 0;
+ }
+
+ if (len > len_avail - offset)
+ len = len_avail - offset;
+ memcpy (readbuf, buf + offset, len);
+
+ return len;
+ }
+
if (strcmp (annex, "processes") != 0)
return 0;
@@ -4942,7 +4994,7 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
if (offset == 0)
{
if (len_avail != -1 && len_avail != 0)
- obstack_free (&obstack, NULL);
+ obstack_free (&obstack, NULL);
len_avail = 0;
buf = NULL;
obstack_init (&obstack);
@@ -4950,60 +5002,63 @@ linux_nat_xfer_osdata (struct target_ops *ops, enum target_object object,
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])
- || NAMELEN (dp) > sizeof ("4294967295") - 1)
- continue;
-
- sprintf (procentry, "/proc/%s", dp->d_name);
- if (stat (procentry, &statbuf) == 0
- && S_ISDIR (statbuf.st_mode))
- {
- char *pathname;
- FILE *f;
- char cmd[MAXPATHLEN + 1];
- struct passwd *entry;
-
- pathname = xstrprintf ("/proc/%s/cmdline", dp->d_name);
- entry = getpwuid (statbuf.st_uid);
-
- if ((f = fopen (pathname, "r")) != NULL)
- {
- size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
- if (len > 0)
- {
- int i;
- for (i = 0; i < len; i++)
- if (cmd[i] == '\0')
- cmd[i] = ' ';
- cmd[len] = '\0';
-
- obstack_xml_printf (
- &obstack,
- "- "
- "%s"
- "%s"
- "%s"
- "
",
- dp->d_name,
- entry ? entry->pw_name : "?",
- cmd);
- }
- fclose (f);
- }
-
- xfree (pathname);
- }
- }
-
- closedir (dirp);
- }
+ {
+ struct dirent *dp;
+
+ 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;
+
+ sprintf (procentry, "/proc/%s", dp->d_name);
+ if (stat (procentry, &statbuf) == 0
+ && S_ISDIR (statbuf.st_mode))
+ {
+ char *pathname;
+ FILE *f;
+ char cmd[MAXPATHLEN + 1];
+ struct passwd *entry;
+
+ pathname = xstrprintf ("/proc/%s/cmdline", dp->d_name);
+ entry = getpwuid (statbuf.st_uid);
+
+ if ((f = fopen (pathname, "r")) != NULL)
+ {
+ size_t len = fread (cmd, 1, sizeof (cmd) - 1, f);
+
+ if (len > 0)
+ {
+ int i;
+
+ for (i = 0; i < len; i++)
+ if (cmd[i] == '\0')
+ cmd[i] = ' ';
+ cmd[len] = '\0';
+
+ obstack_xml_printf (
+ &obstack,
+ "- "
+ "%s"
+ "%s"
+ "%s"
+ "
",
+ dp->d_name,
+ entry ? entry->pw_name : "?",
+ cmd);
+ }
+ fclose (f);
+ }
+
+ xfree (pathname);
+ }
+ }
+
+ closedir (dirp);
+ }
obstack_grow_str0 (&obstack, "\n");
buf = obstack_finish (&obstack);
@@ -5478,6 +5533,7 @@ linux_nat_core_of_thread_1 (ptid_t ptid)
for (;;)
{
int n;
+
content = xrealloc (content, content_read + 1024);
n = fread (content + content_read, 1, 1024, f);
content_read += n;
@@ -5491,15 +5547,21 @@ linux_nat_core_of_thread_1 (ptid_t ptid)
make_cleanup (xfree, content);
p = strchr (content, '(');
- p = strchr (p, ')') + 2; /* skip ")" and a whitespace. */
+
+ /* 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. */
- p = strtok_r (p, " ", &ts);
- for (i = 0; i != 36; ++i)
+ if (p != NULL)
+ p = strtok_r (p, " ", &ts);
+ for (i = 0; p != NULL && i != 36; ++i)
p = strtok_r (NULL, " ", &ts);
- if (sscanf (p, "%d", &core) == 0)
+ if (p == NULL || sscanf (p, "%d", &core) == 0)
core = -1;
do_cleanups (back_to);
@@ -5513,6 +5575,7 @@ int
linux_nat_core_of_thread (struct target_ops *ops, ptid_t ptid)
{
struct lwp_info *info = find_lwp_pid (ptid);
+
if (info)
return info->core;
return -1;