X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Flinux-nat.c;h=93adfcd4e0df2c87927dd0b6f73be81c84ea3277;hb=91158a569dc571a9916dfad98c6c95ce789ad18d;hp=3afe9dd21283746ef477fd8b60292d1e22a9cf25;hpb=ddabfc735b012068343f76ec05226033eb57fa22;p=binutils-gdb.git diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c index 3afe9dd2128..93adfcd4e0d 100644 --- a/gdb/linux-nat.c +++ b/gdb/linux-nat.c @@ -270,8 +270,6 @@ this platform.")); #endif /* !HAVE_PERSONALITY */ } -static int linux_parent_pid; - struct simple_pid_list { int pid; @@ -370,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; @@ -385,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; @@ -405,8 +405,6 @@ linux_record_stopped_pid (int pid, int status) static void linux_tracefork_child (void) { - int ret; - ptrace (PTRACE_TRACEME, 0, 0, 0); kill (getpid (), SIGSTOP); fork (); @@ -681,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; @@ -867,7 +865,6 @@ holding the child stopped. Try \"set detach-on-fork\" or \ } else { - struct thread_info *tp; struct inferior *parent_inf, *child_inf; struct lwp_info *lp; struct program_space *parent_pspace; @@ -1651,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) @@ -1663,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; } } @@ -1752,7 +1751,6 @@ linux_nat_detach (struct target_ops *ops, char *args, int from_tty) { int pid; int status; - enum target_signal sig; struct lwp_info *main_lwp; pid = GET_PID (inferior_ptid); @@ -2215,8 +2213,6 @@ linux_handle_extended_wait (struct lwp_info *lp, int status, ourstatus->kind = TARGET_WAITKIND_VFORKED; else { - struct cleanup *old_chain; - ourstatus->kind = TARGET_WAITKIND_IGNORE; new_lp = add_lwp (BUILD_LWP (new_pid, GET_PID (lp->ptid))); new_lp->cloned = 1; @@ -2475,7 +2471,6 @@ static int linux_nat_has_pending_sigint (int pid) { sigset_t pending, blocked, ignored; - int i; linux_proc_pending_signals (pid, &pending, &blocked, &ignored); @@ -3631,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; } @@ -3811,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); @@ -4059,7 +4061,6 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR, long long addr, endaddr, size, offset, inode; char permissions[8], device[8], filename[MAXPATHLEN]; int read, write, exec; - int ret; struct cleanup *cleanup; /* Compose the filename for the /proc memory map, and open it. */ @@ -4086,8 +4087,8 @@ linux_nat_find_memory_regions (int (*func) (CORE_ADDR, if (info_verbose) { fprintf_filtered (gdb_stdout, - "Save segment, %lld bytes at %s (%c%c%c)", - size, paddress (target_gdbarch, addr), + "Save segment, %s bytes at %s (%c%c%c)", + plongest (size), paddress (target_gdbarch, addr), read ? 'r' : ' ', write ? 'w' : ' ', exec ? 'x' : ' '); if (filename[0]) @@ -4133,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); @@ -4152,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 @@ -4174,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); @@ -4187,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++; } @@ -4202,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 @@ -4350,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; @@ -4367,13 +4368,11 @@ static char * linux_nat_make_corefile_notes (bfd *obfd, int *note_size) { struct linux_nat_corefile_thread_data thread_args; - struct cleanup *old_chain; /* The variable size must be >= sizeof (prpsinfo_t.pr_fname). */ char fname[16] = { '\0' }; /* The variable size must be >= sizeof (prpsinfo_t.pr_psargs). */ char psargs[80] = { '\0' }; char *note_data = NULL; - ptid_t current_ptid = inferior_ptid; ptid_t filter = pid_to_ptid (ptid_get_pid (inferior_ptid)); gdb_byte *auxv; int auxv_len; @@ -4443,7 +4442,6 @@ linux_nat_info_proc_cmd (char *args, int from_tty) int cwd_f = 1; int exe_f = 1; int mappings_f = 0; - int environ_f = 0; int status_f = 0; int stat_f = 0; int all = 0; @@ -4509,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 @@ -4604,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); @@ -4898,7 +4898,6 @@ linux_proc_pending_signals (int pid, sigset_t *pending, sigset_t *blocked, sigse { FILE *procfile; char buffer[MAXPATHLEN], fname[MAXPATHLEN]; - int signum; struct cleanup *cleanup; sigemptyset (pending); @@ -4935,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. */ @@ -4948,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; @@ -4956,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); @@ -4964,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); @@ -5363,7 +5404,6 @@ linux_nat_stop_lwp (struct lwp_info *lwp, void *data) { if (!lwp->stopped) { - int pid, status; ptid_t ptid = lwp->ptid; if (debug_linux_nat) @@ -5493,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; @@ -5506,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); @@ -5528,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; @@ -5624,8 +5672,6 @@ extern initialize_file_ftype _initialize_linux_nat; void _initialize_linux_nat (void) { - sigset_t mask; - add_info ("proc", linux_nat_info_proc_cmd, _("\ Show /proc process information about any running process.\n\ Specify any process id, or use the program being debugged by default.\n\