#include "gdbthread.h"
#include "gdbcmd.h"
#include "regcache.h"
+#include "regset.h"
#include "inf-ptrace.h"
#include "auxv.h"
#include <sys/param.h> /* for MAXPATHLEN */
ret = ptrace (PTRACE_KILL, second_pid, 0, 0);
if (ret != 0)
warning (_("linux_test_for_tracefork: failed to kill second child"));
+ my_waitpid (second_pid, &status, 0);
}
}
else
struct thread_info *thr;
thr = iterate_over_threads (find_thread_from_lwp, &lp->ptid);
- if (thr && !ptid_equal (thr->ptid, inferior_ptid))
- delete_thread (thr->ptid);
- else
- record_dead_thread (thr->ptid);
+ if (thr)
+ {
+ if (!ptid_equal (thr->ptid, inferior_ptid))
+ delete_thread (thr->ptid);
+ else
+ record_dead_thread (thr->ptid);
+ }
}
delete_lwp (lp->ptid);
just pass off to linux_handle_extended_wait, but if it reports a
clone event we need to add the new LWP to our list (and not report
the trap to higher layers). This function returns non-zero if
- the event should be ignored and we should wait again. */
+ the event should be ignored and we should wait again. If STOPPING
+ is true, the new LWP remains stopped, otherwise it is continued. */
static int
-linux_nat_handle_extended (struct lwp_info *lp, int status)
+linux_nat_handle_extended (struct lwp_info *lp, int status, int stopping)
{
linux_handle_extended_wait (GET_LWP (lp->ptid), status,
&lp->waitstatus);
new_lp = add_lwp (BUILD_LWP (lp->waitstatus.value.related_pid,
GET_PID (inferior_ptid)));
new_lp->cloned = 1;
- new_lp->stopped = 1;
+
+ if (stopping)
+ new_lp->stopped = 1;
+ else
+ ptrace (PTRACE_CONT, lp->waitstatus.value.related_pid, 0, 0);
lp->waitstatus.kind = TARGET_WAITKIND_IGNORE;
fprintf_unfiltered (gdb_stdlog,
"WL: Handling extended status 0x%06x\n",
status);
- if (linux_nat_handle_extended (lp, status))
+ if (linux_nat_handle_extended (lp, status, 1))
return wait_lwp (lp);
}
fprintf_unfiltered (gdb_stdlog,
"LLW: Handling extended status 0x%06x\n",
status);
- if (linux_nat_handle_extended (lp, status))
+ if (linux_nat_handle_extended (lp, status, 0))
{
status = 0;
continue;
{
int signo = target_signal_from_host (WSTOPSIG (status));
- if (signal_stop_state (signo) == 0
+ /* If we get a signal while single-stepping, we may need special
+ care, e.g. to skip the signal handler. Defer to common code. */
+ if (!lp->step
+ && signal_stop_state (signo) == 0
&& signal_print_state (signo) == 0
&& signal_pass_state (signo) == 1)
{
will first do a lookup for the process based upon the
passed-in pid. If that fails we will get either -ESRCH
or -EPERM, otherwise the child exists and is alive. */
- if (errno == -ESRCH || errno == -EPERM)
+ if (errno == ESRCH || errno == EPERM)
return 0;
return 1;
gdb_fpxregset_t fpxregs;
#endif
unsigned long lwp = ptid_get_lwp (ptid);
+ struct gdbarch *gdbarch = current_gdbarch;
+ const struct regset *regset;
+ int core_regset_p;
+
+ core_regset_p = gdbarch_regset_from_core_section_p (gdbarch);
+ if (core_regset_p
+ && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg",
+ sizeof (gregs))) != NULL
+ && regset->collect_regset != NULL)
+ regset->collect_regset (regset, current_regcache, -1,
+ &gregs, sizeof (gregs));
+ else
+ fill_gregset (&gregs, -1);
- fill_gregset (&gregs, -1);
note_data = (char *) elfcore_write_prstatus (obfd,
note_data,
note_size,
lwp,
stop_signal, &gregs);
- fill_fpregset (&fpregs, -1);
+ if (core_regset_p
+ && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
+ sizeof (fpregs))) != NULL
+ && regset->collect_regset != NULL)
+ regset->collect_regset (regset, current_regcache, -1,
+ &fpregs, sizeof (fpregs));
+ else
+ fill_fpregset (&fpregs, -1);
+
note_data = (char *) elfcore_write_prfpreg (obfd,
note_data,
note_size,
&fpregs, sizeof (fpregs));
+
#ifdef FILL_FPXREGSET
- fill_fpxregset (&fpxregs, -1);
+ if (core_regset_p
+ && (regset = gdbarch_regset_from_core_section (gdbarch, ".reg-xfp",
+ sizeof (fpxregs))) != NULL
+ && regset->collect_regset != NULL)
+ regset->collect_regset (regset, current_regcache, -1,
+ &fpxregs, sizeof (fpxregs));
+ else
+ fill_fpxregset (&fpxregs, -1);
+
note_data = (char *) elfcore_write_prxfpreg (obfd,
note_data,
note_size,
note_data = thread_args.note_data;
}
- auxv_len = target_auxv_read (¤t_target, &auxv);
+ auxv_len = target_read_alloc (¤t_target, TARGET_OBJECT_AUXV,
+ NULL, &auxv);
if (auxv_len > 0)
{
note_data = elfcore_write_note (obfd, note_data, note_size,
void
linux_nat_add_target (struct target_ops *t)
{
- extern void thread_db_init (struct target_ops *);
-
/* Save the provided single-threaded target. We save this in a separate
variable because another target we've inherited from (e.g. inf-ptrace)
may have saved a pointer to T; we want to use it for the final