#include "gdbcmd.h"
#include "regcache.h"
#include "regset.h"
+#include "inf-child.h"
#include "inf-ptrace.h"
#include "auxv.h"
#include <sys/param.h> /* for MAXPATHLEN */
#include "symfile.h"
#include "agent.h"
#include "tracepoint.h"
+#include "exceptions.h"
+#include "linux-ptrace.h"
+#include "buffer.h"
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
/* The method to call, if any, when the siginfo object needs to be
converted between the layout returned by ptrace, and the layout in
the architecture of the inferior. */
-static int (*linux_nat_siginfo_fixup) (struct siginfo *,
+static int (*linux_nat_siginfo_fixup) (siginfo_t *,
gdb_byte *,
int);
const gdb_byte *,
ULONGEST, LONGEST);
-static int debug_linux_nat;
+static unsigned int debug_linux_nat;
static void
show_debug_linux_nat (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
{
linux_enable_event_reporting (pid_to_ptid (pid));
linux_enable_tracesysgood (pid_to_ptid (pid));
+ linux_ptrace_init_warnings ();
}
static void
{
linux_enable_event_reporting (ptid);
linux_enable_tracesysgood (ptid);
+ linux_ptrace_init_warnings ();
}
/* Return the number of known LWPs in the tgid given by PID. */
for (signo = 1; signo < NSIG; signo++)
{
- int target_signo = target_signal_from_host (signo);
+ int target_signo = gdb_signal_from_host (signo);
if (target_signo < numsigs && pass_signals[target_signo])
sigaddset (&pass_mask, signo);
}
pid_t child_pid = GET_PID (inferior_ptid);
ptid_t child_ptid = ptid_build (child_pid, child_pid, 0);
- gdb_assert (!is_lwp (inferior_ptid));
gdb_assert (find_lwp_pid (child_ptid) == NULL);
child_lp = add_lwp (child_ptid);
child_lp->stopped = 1;
struct lwp_info *lp;
int status;
ptid_t ptid;
+ volatile struct gdb_exception ex;
/* Make sure we report all signals during attach. */
linux_nat_pass_signals (0, NULL);
- linux_ops->to_attach (ops, args, from_tty);
+ TRY_CATCH (ex, RETURN_MASK_ERROR)
+ {
+ linux_ops->to_attach (ops, args, from_tty);
+ }
+ if (ex.reason < 0)
+ {
+ pid_t pid = parse_pid_to_attach (args);
+ struct buffer buffer;
+ char *message, *buffer_s;
+
+ message = xstrdup (ex.message);
+ make_cleanup (xfree, message);
+
+ buffer_init (&buffer);
+ linux_ptrace_attach_warnings (pid, &buffer);
+
+ buffer_grow_str0 (&buffer, "");
+ buffer_s = buffer_finish (&buffer);
+ make_cleanup (xfree, buffer_s);
+
+ throw_error (ex.error, "%s%s", buffer_s, message);
+ }
/* The ptrace base target adds the main thread with (pid,0,0)
format. Decorate it with lwp info. */
}
else if (WIFSIGNALED (status))
{
- enum target_signal signo;
+ enum gdb_signal signo;
target_terminal_ours ();
target_mourn_inferior ();
- signo = target_signal_from_host (WTERMSIG (status));
+ signo = gdb_signal_from_host (WTERMSIG (status));
error (_("Unable to attach: program terminated with signal "
"%s, %s."),
- target_signal_to_name (signo),
- target_signal_to_string (signo));
+ gdb_signal_to_name (signo),
+ gdb_signal_to_string (signo));
}
internal_error (__FILE__, __LINE__,
static int
get_pending_status (struct lwp_info *lp, int *status)
{
- enum target_signal signo = TARGET_SIGNAL_0;
+ enum gdb_signal signo = GDB_SIGNAL_0;
/* If we paused threads momentarily, we may have stored pending
events in lp->status or lp->waitstatus (see stop_wait_callback),
stop_signal make sense as a real signal to pass to the inferior.
Some catchpoint related events, like
TARGET_WAITKIND_(V)FORK|EXEC|SYSCALL, have their stop_signal set
- to TARGET_SIGNAL_SIGTRAP when the catchpoint triggers. But,
+ to GDB_SIGNAL_SIGTRAP when the catchpoint triggers. But,
those traps are debug API (ptrace in our case) related and
induced; the inferior wouldn't see them if it wasn't being
traced. Hence, we should never pass them to the inferior, even
this is really a corner case. */
if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
- signo = TARGET_SIGNAL_0; /* a pending ptrace event, not a real signal. */
+ signo = GDB_SIGNAL_0; /* a pending ptrace event, not a real signal. */
else if (lp->status)
- signo = target_signal_from_host (WSTOPSIG (lp->status));
+ signo = gdb_signal_from_host (WSTOPSIG (lp->status));
else if (non_stop && !is_executing (lp->ptid))
{
struct thread_info *tp = find_thread_ptid (lp->ptid);
*status = 0;
- if (signo == TARGET_SIGNAL_0)
+ if (signo == GDB_SIGNAL_0)
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"GPT: lwp %s had signal %s, "
"but it is in no pass state\n",
target_pid_to_str (lp->ptid),
- target_signal_to_string (signo));
+ gdb_signal_to_string (signo));
}
else
{
- *status = W_STOPCODE (target_signal_to_host (signo));
+ *status = W_STOPCODE (gdb_signal_to_host (signo));
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"GPT: lwp %s has pending signal %s\n",
target_pid_to_str (lp->ptid),
- target_signal_to_string (signo));
+ gdb_signal_to_string (signo));
}
return 0;
pid = GET_PID (inferior_ptid);
- if (target_can_async_p ())
- linux_nat_async (NULL, 0);
+ /* Don't unregister from the event loop, as there may be other
+ inferiors running. */
/* Stop all threads before detaching. ptrace requires that the
thread is stopped to sucessfully detach. */
the current fork, and context-switch to the first
available. */
linux_fork_detach (args, from_tty);
-
- if (non_stop && target_can_async_p ())
- target_async (inferior_event_handler, 0);
}
else
linux_ops->to_detach (ops, args, from_tty);
/* Resume LP. */
static void
-resume_lwp (struct lwp_info *lp, int step)
+resume_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
{
if (lp->stopped)
{
{
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
- "RC: PTRACE_CONT %s, 0, 0 (resuming sibling)\n",
- target_pid_to_str (lp->ptid));
+ "RC: Resuming sibling %s, %s, %s\n",
+ target_pid_to_str (lp->ptid),
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo))
+ : "0"),
+ step ? "step" : "resume");
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops,
pid_to_ptid (GET_LWP (lp->ptid)),
- step, TARGET_SIGNAL_0);
+ step, signo);
lp->stopped = 0;
lp->step = step;
- memset (&lp->siginfo, 0, sizeof (lp->siginfo));
lp->stopped_by_watchpoint = 0;
}
else
}
}
+/* Resume LWP, with the last stop signal, if it is in pass state. */
+
static int
-resume_callback (struct lwp_info *lp, void *data)
+linux_nat_resume_callback (struct lwp_info *lp, void *data)
{
- resume_lwp (lp, 0);
+ enum gdb_signal signo = GDB_SIGNAL_0;
+
+ if (lp->stopped)
+ {
+ struct thread_info *thread;
+
+ thread = find_thread_ptid (lp->ptid);
+ if (thread != NULL)
+ {
+ if (signal_pass_state (thread->suspend.stop_signal))
+ signo = thread->suspend.stop_signal;
+ thread->suspend.stop_signal = GDB_SIGNAL_0;
+ }
+ }
+
+ resume_lwp (lp, 0, signo);
return 0;
}
static void
linux_nat_resume (struct target_ops *ops,
- ptid_t ptid, int step, enum target_signal signo)
+ ptid_t ptid, int step, enum gdb_signal signo)
{
sigset_t prev_mask;
struct lwp_info *lp;
"LLR: Preparing to %s %s, %s, inferior_ptid %s\n",
step ? "step" : "resume",
target_pid_to_str (ptid),
- (signo != TARGET_SIGNAL_0
- ? strsignal (target_signal_to_host (signo)) : "0"),
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo)) : "0"),
target_pid_to_str (inferior_ptid));
block_child_signals (&prev_mask);
/* FIXME: What should we do if we are supposed to continue
this thread with a signal? */
- gdb_assert (signo == TARGET_SIGNAL_0);
- signo = target_signal_from_host (WSTOPSIG (lp->status));
+ gdb_assert (signo == GDB_SIGNAL_0);
+ signo = gdb_signal_from_host (WSTOPSIG (lp->status));
lp->status = 0;
}
}
{
/* FIXME: What should we do if we are supposed to continue
this thread with a signal? */
- gdb_assert (signo == TARGET_SIGNAL_0);
+ gdb_assert (signo == GDB_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
}
/* Mark LWP as not stopped to prevent it from being continued by
- resume_callback. */
+ linux_nat_resume_callback. */
lp->stopped = 0;
if (resume_many)
- iterate_over_lwps (ptid, resume_callback, NULL);
+ iterate_over_lwps (ptid, linux_nat_resume_callback, NULL);
/* Convert to something the lower layer understands. */
ptid = pid_to_ptid (GET_LWP (lp->ptid));
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, ptid, step, signo);
- memset (&lp->siginfo, 0, sizeof (lp->siginfo));
lp->stopped_by_watchpoint = 0;
if (debug_linux_nat)
"LLR: %s %s, %s (resume event thread)\n",
step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
target_pid_to_str (ptid),
- (signo != TARGET_SIGNAL_0
- ? strsignal (target_signal_to_host (signo)) : "0"));
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo)) : "0"));
restore_child_signals_mask (&prev_mask);
if (target_can_async_p ())
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
- lp->step, TARGET_SIGNAL_0);
+ lp->step, GDB_SIGNAL_0);
return 1;
}
/* This won't actually modify the breakpoint list, but will
physically remove the breakpoints from the child. */
- detach_breakpoints (new_pid);
+ detach_breakpoints (ptid_build (new_pid, new_pid, 0));
/* Retain child fork in ptrace (stopped) state. */
if (!find_fork_pid (new_pid))
RT signal, it can only be queued once. We need to be
careful to not resume the LWP if we wanted it to
stop. In that case, we'll leave the SIGSTOP pending.
- It will later be reported as TARGET_SIGNAL_0. */
+ It will later be reported as GDB_SIGNAL_0. */
tp = find_thread_ptid (new_lp->ptid);
if (tp != NULL && tp->stop_requested)
new_lp->last_resume_kind = resume_stop;
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (new_lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (new_pid),
- 0, TARGET_SIGNAL_0);
+ 0, GDB_SIGNAL_0);
new_lp->stopped = 0;
}
}
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
- 0, TARGET_SIGNAL_0);
+ 0, GDB_SIGNAL_0);
return 1;
}
return status;
}
-/* Save the most recent siginfo for LP. This is currently only called
- for SIGTRAP; some ports use the si_addr field for
- target_stopped_data_address. In the future, it may also be used to
- restore the siginfo of requeued signals. */
-
-static void
-save_siginfo (struct lwp_info *lp)
-{
- errno = 0;
- ptrace (PTRACE_GETSIGINFO, GET_LWP (lp->ptid),
- (PTRACE_TYPE_ARG3) 0, &lp->siginfo);
-
- if (errno != 0)
- memset (&lp->siginfo, 0, sizeof (lp->siginfo));
-}
-
/* Send a SIGSTOP to LP. */
static int
if (WSTOPSIG (status) != SIGSTOP)
{
- if (linux_nat_status_is_event (status))
- {
- /* If a LWP other than the LWP that we're reporting an
- event for has hit a GDB breakpoint (as opposed to
- some random trap signal), then just arrange for it to
- hit it again later. We don't keep the SIGTRAP status
- and don't forward the SIGTRAP signal to the LWP. We
- will handle the current event, eventually we will
- resume all LWPs, and this one will get its breakpoint
- trap again.
-
- If we do not do this, then we run the risk that the
- user will delete or disable the breakpoint, but the
- thread will have already tripped on it. */
-
- /* Save the trap's siginfo in case we need it later. */
- save_siginfo (lp);
-
- save_sigtrap (lp);
-
- /* Now resume this LWP and get the SIGSTOP event. */
- errno = 0;
- ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "PTRACE_CONT %s, 0, 0 (%s)\n",
- target_pid_to_str (lp->ptid),
- errno ? safe_strerror (errno) : "OK");
-
- fprintf_unfiltered (gdb_stdlog,
- "SWC: Candidate SIGTRAP event in %s\n",
- target_pid_to_str (lp->ptid));
- }
- /* Hold this event/waitstatus while we check to see if
- there are any more (we still want to get that SIGSTOP). */
- stop_wait_callback (lp, NULL);
-
- /* Hold the SIGTRAP for handling by linux_nat_wait. If
- there's another event, throw it back into the
- queue. */
- if (lp->status)
- {
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SWC: kill %s, %s\n",
- target_pid_to_str (lp->ptid),
- status_to_str ((int) status));
- kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
- }
+ /* The thread was stopped with a signal other than SIGSTOP. */
- /* Save the sigtrap event. */
- lp->status = status;
- return 0;
- }
- else
- {
- /* The thread was stopped with a signal other than
- SIGSTOP, and didn't accidentally trip a breakpoint. */
+ save_sigtrap (lp);
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "SWC: Pending event %s in %s\n",
- status_to_str ((int) status),
- target_pid_to_str (lp->ptid));
- }
- /* Now resume this LWP and get the SIGSTOP event. */
- errno = 0;
- ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0, 0);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SWC: PTRACE_CONT %s, 0, 0 (%s)\n",
- target_pid_to_str (lp->ptid),
- errno ? safe_strerror (errno) : "OK");
-
- /* Hold this event/waitstatus while we check to see if
- there are any more (we still want to get that SIGSTOP). */
- stop_wait_callback (lp, NULL);
-
- /* If the lp->status field is still empty, use it to
- hold this event. If not, then this event must be
- returned to the event queue of the LWP. */
- if (lp->status)
- {
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "SWC: kill %s, %s\n",
- target_pid_to_str (lp->ptid),
- status_to_str ((int) status));
- }
- kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (status));
- }
- else
- lp->status = status;
- return 0;
- }
+ if (debug_linux_nat)
+ fprintf_unfiltered (gdb_stdlog,
+ "SWC: Pending event %s in %s\n",
+ status_to_str ((int) status),
+ target_pid_to_str (lp->ptid));
+
+ /* Save the sigtrap event. */
+ lp->status = status;
+ gdb_assert (!lp->stopped);
+ gdb_assert (lp->signalled);
+ lp->stopped = 1;
}
else
{
/* We caught the SIGSTOP that we intended to catch, so
there's no SIGSTOP pending. */
+
+ if (debug_linux_nat)
+ fprintf_unfiltered (gdb_stdlog,
+ "SWC: Delayed SIGSTOP caught for %s.\n",
+ target_pid_to_str (lp->ptid));
+
lp->stopped = 1;
+
+ /* Reset SIGNALLED only after the stop_wait_callback call
+ above as it does gdb_assert on SIGNALLED. */
lp->signalled = 0;
}
}
fprintf_unfiltered (gdb_stdlog,
"SARC: re-resuming LWP %ld\n",
GET_LWP (lp->ptid));
- resume_lwp (lp, lp->step);
+ resume_lwp (lp, lp->step, GDB_SIGNAL_0);
}
else
{
}
if (linux_nat_status_is_event (status))
- {
- /* Save the trap's siginfo in case we need it later. */
- save_siginfo (lp);
-
- save_sigtrap (lp);
- }
+ save_sigtrap (lp);
/* Check if the thread has exited. */
if ((WIFEXITED (status) || WIFSIGNALED (status))
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
- lp->step, TARGET_SIGNAL_0);
+ lp->step, GDB_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"LLW: %s %s, 0, 0 (discard SIGSTOP)\n",
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
- lp->step, TARGET_SIGNAL_0);
+ lp->step, GDB_SIGNAL_0);
if (debug_linux_nat)
fprintf_unfiltered (gdb_stdlog,
"LLW: %s %s, 0, 0 (discard SIGINT)\n",
lp = NULL;
}
- if (lp && lp->signalled && lp->last_resume_kind != resume_stop)
- {
- /* A pending SIGSTOP may interfere with the normal stream of
- events. In a typical case where interference is a problem,
- we have a SIGSTOP signal pending for LWP A while
- single-stepping it, encounter an event in LWP B, and take the
- pending SIGSTOP while trying to stop LWP A. After processing
- the event in LWP B, LWP A is continued, and we'll never see
- the SIGTRAP associated with the last time we were
- single-stepping LWP A. */
-
- /* Resume the thread. It should halt immediately returning the
- pending SIGSTOP. */
- registers_changed ();
- if (linux_nat_prepare_to_resume != NULL)
- linux_nat_prepare_to_resume (lp);
- linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
- lp->step, TARGET_SIGNAL_0);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: %s %s, 0, 0 (expect SIGSTOP)\n",
- lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
- target_pid_to_str (lp->ptid));
- lp->stopped = 0;
- gdb_assert (lp->resumed);
-
- /* Catch the pending SIGSTOP. */
- status = lp->status;
- lp->status = 0;
-
- stop_wait_callback (lp, NULL);
-
- /* If the lp->status field isn't empty, we caught another signal
- while flushing the SIGSTOP. Return it back to the event
- queue of the LWP, as we already have an event to handle. */
- if (lp->status)
- {
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: kill %s, %s\n",
- target_pid_to_str (lp->ptid),
- status_to_str (lp->status));
- kill_lwp (GET_LWP (lp->ptid), WSTOPSIG (lp->status));
- }
-
- lp->status = status;
- }
-
if (!target_can_async_p ())
{
/* Causes SIGINT to be passed on to the attached process. */
if (WIFSTOPPED (status))
{
- enum target_signal signo = target_signal_from_host (WSTOPSIG (status));
+ enum gdb_signal signo = gdb_signal_from_host (WSTOPSIG (status));
/* When using hardware single-step, we need to report every signal.
Otherwise, signals in pass_mask may be short-circuited. */
lp->step ?
"PTRACE_SINGLESTEP" : "PTRACE_CONT",
target_pid_to_str (lp->ptid),
- (signo != TARGET_SIGNAL_0
- ? strsignal (target_signal_to_host (signo))
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo))
: "0"));
lp->stopped = 0;
goto retry;
/* Only do the below in all-stop, as we currently use SIGINT
to implement target_stop (see linux_nat_stop) in
non-stop. */
- if (signo == TARGET_SIGNAL_INT && signal_pass_state (signo) == 0)
+ if (signo == GDB_SIGNAL_INT && signal_pass_state (signo) == 0)
{
/* If ^C/BREAK is typed at the tty/console, SIGINT gets
forwarded to the entire process group, that is, all LWPs
/* A thread that has been requested to stop by GDB with
target_stop, and it stopped cleanly, so report as SIG0. The
use of SIGSTOP is an implementation detail. */
- ourstatus->value.sig = TARGET_SIGNAL_0;
+ ourstatus->value.sig = GDB_SIGNAL_0;
}
if (ourstatus->kind == TARGET_WAITKIND_EXITED
if (linux_nat_prepare_to_resume != NULL)
linux_nat_prepare_to_resume (lp);
linux_ops->to_resume (linux_ops, pid_to_ptid (GET_LWP (lp->ptid)),
- lp->step, TARGET_SIGNAL_0);
+ lp->step, GDB_SIGNAL_0);
lp->stopped = 0;
- memset (&lp->siginfo, 0, sizeof (lp->siginfo));
lp->stopped_by_watchpoint = 0;
}
ptid_t event_ptid;
if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "linux_nat_wait: [%s]\n", target_pid_to_str (ptid));
+ {
+ char *options_string;
+
+ options_string = target_options_to_string (target_options);
+ fprintf_unfiltered (gdb_stdlog,
+ "linux_nat_wait: [%s], [%s]\n",
+ target_pid_to_str (ptid),
+ options_string);
+ xfree (options_string);
+ }
/* Flush the async file first. */
if (target_can_async_p ())
layout of the inferiors' architecture. */
static void
-siginfo_fixup (struct siginfo *siginfo, gdb_byte *inf_siginfo, int direction)
+siginfo_fixup (siginfo_t *siginfo, gdb_byte *inf_siginfo, int direction)
{
int done = 0;
if (!done)
{
if (direction == 1)
- memcpy (siginfo, inf_siginfo, sizeof (struct siginfo));
+ memcpy (siginfo, inf_siginfo, sizeof (siginfo_t));
else
- memcpy (inf_siginfo, siginfo, sizeof (struct siginfo));
+ memcpy (inf_siginfo, siginfo, sizeof (siginfo_t));
}
}
const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
{
int pid;
- struct siginfo siginfo;
- gdb_byte inf_siginfo[sizeof (struct siginfo)];
+ siginfo_t siginfo;
+ gdb_byte inf_siginfo[sizeof (siginfo_t)];
gdb_assert (object == TARGET_OBJECT_SIGNAL_INFO);
gdb_assert (readbuf || writebuf);
linux_nat_collect_thread_registers (const struct regcache *regcache,
ptid_t ptid, bfd *obfd,
char *note_data, int *note_size,
- enum target_signal stop_signal)
+ enum gdb_signal stop_signal)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
const struct regset *regset;
note_data = (char *) elfcore_write_prstatus
(obfd, note_data, note_size, ptid_get_lwp (ptid),
- target_signal_to_host (stop_signal), &gregs);
+ gdb_signal_to_host (stop_signal), &gregs);
if (core_regset_p
&& (regset = gdbarch_regset_from_core_section (gdbarch, ".reg2",
gdb_assert (arg != NULL);
/* Unpause all */
- target_resume (*ptid, 0, TARGET_SIGNAL_0);
+ target_resume (*ptid, 0, GDB_SIGNAL_0);
}
static VEC(static_tracepoint_marker_p) *
memcpy (s, "qTfSTM", sizeof ("qTfSTM"));
s[sizeof ("qTfSTM")] = 0;
- agent_run_command (pid, s);
+ agent_run_command (pid, s, strlen (s) + 1);
old_chain = make_cleanup (free_current_marker, &marker);
make_cleanup (cleanup_target_stop, &ptid);
memcpy (s, "qTsSTM", sizeof ("qTsSTM"));
s[sizeof ("qTsSTM")] = 0;
- agent_run_command (pid, s);
+ agent_run_command (pid, s, strlen (s) + 1);
p = s;
}
return;
}
-/* Stop an LWP, and push a TARGET_SIGNAL_0 stop status if no other
+/* Stop an LWP, and push a GDB_SIGNAL_0 stop status if no other
event came out. */
static int
inferior. */
void
linux_nat_set_siginfo_fixup (struct target_ops *t,
- int (*siginfo_fixup) (struct siginfo *,
+ int (*siginfo_fixup) (siginfo_t *,
gdb_byte *,
int))
{
linux_nat_prepare_to_resume = prepare_to_resume;
}
-/* Return the saved siginfo associated with PTID. */
-struct siginfo *
-linux_nat_get_siginfo (ptid_t ptid)
+/* See linux-nat.h. */
+
+int
+linux_nat_get_siginfo (ptid_t ptid, siginfo_t *siginfo)
{
- struct lwp_info *lp = find_lwp_pid (ptid);
+ int pid;
- gdb_assert (lp != NULL);
+ pid = GET_LWP (ptid);
+ if (pid == 0)
+ pid = GET_PID (ptid);
- return &lp->siginfo;
+ errno = 0;
+ ptrace (PTRACE_GETSIGINFO, pid, (PTRACE_TYPE_ARG3) 0, siginfo);
+ if (errno != 0)
+ {
+ memset (siginfo, 0, sizeof (*siginfo));
+ return 0;
+ }
+ return 1;
}
/* Provide a prototype to silence -Wmissing-prototypes. */
void
_initialize_linux_nat (void)
{
- add_setshow_zinteger_cmd ("lin-lwp", class_maintenance,
- &debug_linux_nat, _("\
+ add_setshow_zuinteger_cmd ("lin-lwp", class_maintenance,
+ &debug_linux_nat, _("\
Set debugging of GNU/Linux lwp module."), _("\
Show debugging of GNU/Linux lwp module."), _("\
Enables printf debugging output."),
- NULL,
- show_debug_linux_nat,
- &setdebuglist, &showdebuglist);
+ NULL,
+ show_debug_linux_nat,
+ &setdebuglist, &showdebuglist);
/* Save this mask as the default. */
sigprocmask (SIG_SETMASK, NULL, &normal_mask);