/* GNU/Linux native-dependent code common to multiple platforms.
- Copyright (C) 2001-2018 Free Software Foundation, Inc.
+ Copyright (C) 2001-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "target.h"
#include "nat/linux-nat.h"
#include "nat/linux-waitpid.h"
-#include "gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
#include <unistd.h>
#include <sys/syscall.h>
#include "nat/gdb_ptrace.h"
#include <sys/stat.h> /* for struct stat */
#include <fcntl.h> /* for O_RDONLY */
#include "inf-loop.h"
-#include "event-loop.h"
+#include "gdbsupport/event-loop.h"
#include "event-top.h"
#include <pwd.h>
#include <sys/types.h>
#include "nat/linux-osdata.h"
#include "linux-tdep.h"
#include "symfile.h"
-#include "agent.h"
+#include "gdbsupport/agent.h"
#include "tracepoint.h"
-#include "buffer.h"
+#include "gdbsupport/buffer.h"
#include "target-descriptions.h"
-#include "filestuff.h"
+#include "gdbsupport/filestuff.h"
#include "objfiles.h"
#include "nat/linux-namespaces.h"
-#include "fileio.h"
-
-#ifndef SPUFS_MAGIC
-#define SPUFS_MAGIC 0x23c9b64e
-#endif
+#include "gdbsupport/fileio.h"
+#include "gdbsupport/scope-exit.h"
+#include "gdbsupport/gdb-sigmask.h"
+#include "debug.h"
/* This comment documents high-level logic of this file.
value);
}
+/* Print a debug statement. Should be used through linux_nat_debug_printf. */
+
+static void ATTRIBUTE_PRINTF (2, 3)
+linux_nat_debug_printf_1 (const char *func_name, const char *fmt, ...)
+{
+ va_list ap;
+ va_start (ap, fmt);
+ debug_prefixed_vprintf ("linux-nat", func_name, fmt, ap);
+ va_end (ap);
+}
+
+#define linux_nat_debug_printf(fmt, ...) \
+ do { \
+ if (debug_linux_nat) \
+ linux_nat_debug_printf_1 (__func__, fmt, ##__VA_ARGS__); \
+ } while (0)
+
struct simple_pid_list
{
int pid;
int status;
struct simple_pid_list *next;
};
-struct simple_pid_list *stopped_pids;
+static struct simple_pid_list *stopped_pids;
/* Whether target_thread_events is in effect. */
static int report_thread_events;
static int kill_lwp (int lwpid, int signo);
-static int stop_callback (struct lwp_info *lp, void *data);
-static int resume_stopped_resumed_lwps (struct lwp_info *lp, void *data);
+static int stop_callback (struct lwp_info *lp);
static void block_child_signals (sigset_t *prev_mask);
static void restore_child_signals_mask (sigset_t *prev_mask);
return count;
}
-/* Call delete_lwp with prototype compatible for make_cleanup. */
+/* Deleter for lwp_info unique_ptr specialisation. */
-static void
-delete_lwp_cleanup (void *lp_voidp)
+struct lwp_deleter
{
- struct lwp_info *lp = (struct lwp_info *) lp_voidp;
+ void operator() (struct lwp_info *lwp) const
+ {
+ delete_lwp (lwp->ptid);
+ }
+};
- delete_lwp (lp->ptid);
-}
+/* A unique_ptr specialisation for lwp_info. */
+
+typedef std::unique_ptr<struct lwp_info, lwp_deleter> lwp_info_up;
/* Target hook for follow_fork. On entry inferior_ptid must be the
ptid of the followed inferior. At return, inferior_ptid will be
unchanged. */
-int
-linux_nat_target::follow_fork (int follow_child, int detach_fork)
+bool
+linux_nat_target::follow_fork (bool follow_child, bool detach_fork)
{
if (!follow_child)
{
{
int child_stop_signal = 0;
bool detach_child = true;
- struct cleanup *old_chain = make_cleanup (delete_lwp_cleanup,
- child_lp);
- linux_target->low_prepare_to_resume (child_lp);
+ /* Move CHILD_LP into a unique_ptr and clear the source pointer
+ to prevent us doing anything stupid with it. */
+ lwp_info_up child_lp_ptr (child_lp);
+ child_lp = nullptr;
+
+ linux_target->low_prepare_to_resume (child_lp_ptr.get ());
/* When debugging an inferior in an architecture that supports
hardware single stepping on a kernel without commit
signo = 0;
ptrace (PTRACE_DETACH, child_pid, 0, signo);
}
-
- do_cleanups (old_chain);
}
else
{
- scoped_restore save_inferior_ptid
- = make_scoped_restore (&inferior_ptid);
- inferior_ptid = child_ptid;
+ /* Switching inferior_ptid is not enough, because then
+ inferior_thread () would crash by not finding the thread
+ in the current inferior. */
+ scoped_restore_current_thread restore_current_thread;
+ thread_info *child = find_thread_ptid (this, child_ptid);
+ switch_to_thread (child);
/* Let the thread_db layer learn about this new process. */
check_for_thread_db ();
if (linux_supports_tracevforkdone ())
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LCFF: waiting for VFORK_DONE on %d\n",
- parent_pid);
+ linux_nat_debug_printf ("waiting for VFORK_DONE on %d",
+ parent_pid);
parent_lp->stopped = 1;
/* We'll handle the VFORK_DONE event like any other
is only the single-step breakpoint at vfork's return
point. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LCFF: no VFORK_DONE "
- "support, sleeping a bit\n");
+ linux_nat_debug_printf ("no VFORK_DONE support, sleeping a bit");
usleep (10000);
check_for_thread_db ();
}
- return 0;
+ return false;
}
\f
\f
-/* Original signal mask. */
-static sigset_t normal_mask;
-
/* Signal mask for use with sigsuspend in linux_nat_wait, initialized in
_initialize_linux_nat. */
static sigset_t suspend_mask;
if (!sigismember (&blocked_mask, SIGCHLD))
sigaddset (&blocked_mask, SIGCHLD);
- sigprocmask (SIG_BLOCK, &blocked_mask, prev_mask);
+ gdb_sigmask (SIG_BLOCK, &blocked_mask, prev_mask);
}
/* Restore child signals mask, previously returned by
static void
restore_child_signals_mask (sigset_t *prev_mask)
{
- sigprocmask (SIG_SETMASK, prev_mask, NULL);
+ gdb_sigmask (SIG_SETMASK, prev_mask, NULL);
}
/* Mask of signals to pass directly to the inferior. */
/* Update signals to pass to the inferior. */
void
-linux_nat_target::pass_signals (int numsigs, unsigned char *pass_signals)
+linux_nat_target::pass_signals
+ (gdb::array_view<const unsigned char> pass_signals)
{
int signo;
for (signo = 1; signo < NSIG; signo++)
{
int target_signo = gdb_signal_from_host (signo);
- if (target_signo < numsigs && pass_signals[target_signo])
+ if (target_signo < pass_signals.size () && pass_signals[target_signo])
sigaddset (&pass_mask, signo);
}
}
\f
/* Prototypes for local functions. */
-static int stop_wait_callback (struct lwp_info *lp, void *data);
-static int resume_stopped_resumed_lwps (struct lwp_info *lp, void *data);
+static int stop_wait_callback (struct lwp_info *lp);
+static int resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid);
static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
\f
struct lwp_info *
iterate_over_lwps (ptid_t filter,
- iterate_over_lwps_ftype callback,
- void *data)
+ gdb::function_view<iterate_over_lwps_ftype> callback)
{
struct lwp_info *lp, *lpnext;
if (lp->ptid.matches (filter))
{
- if ((*callback) (lp, data) != 0)
+ if (callback (lp) != 0)
return lp;
}
}
/* This changes the thread's ptid while preserving the gdb thread
num. Also changes the inferior pid, while preserving the
inferior num. */
- thread_change_ptid (inferior_ptid, new_ptid);
+ thread_change_ptid (linux_target, inferior_ptid, new_ptid);
/* We've just told GDB core that the thread changed target id, but,
in fact, it really is a different thread, with different register
static void
exit_lwp (struct lwp_info *lp)
{
- struct thread_info *th = find_thread_ptid (lp->ptid);
+ struct thread_info *th = find_thread_ptid (linux_target, lp->ptid);
if (th)
{
if (print_thread_events)
- printf_unfiltered (_("[%s exited]\n"), target_pid_to_str (lp->ptid));
+ printf_unfiltered (_("[%s exited]\n"),
+ target_pid_to_str (lp->ptid).c_str ());
delete_thread (th);
}
if (linux_proc_pid_is_stopped (pid))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LNPAW: Attaching to a stopped process\n");
+ linux_nat_debug_printf ("Attaching to a stopped process");
/* The process is definitely stopped. It is in a job control
stop, unless the kernel predates the TASK_STOPPED /
if (!WIFSTOPPED (status))
{
/* The pid we tried to attach has apparently just exited. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "LNPAW: Failed to stop %d: %s",
- pid, status_to_str (status));
+ linux_nat_debug_printf ("Failed to stop %d: %s", pid,
+ status_to_str (status));
return status;
}
if (WSTOPSIG (status) != SIGSTOP)
{
*signalled = 1;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LNPAW: Received %s after attaching\n",
- status_to_str (status));
+ linux_nat_debug_printf ("Received %s after attaching",
+ status_to_str (status));
}
return status;
we have to mask the async mode. */
/* Make sure we report all signals during startup. */
- pass_signals (0, NULL);
+ pass_signals ({});
inf_ptrace_target::create_inferior (exec_file, allargs, env, from_tty);
}
if (err == ESRCH
|| (err == EPERM && linux_proc_pid_is_gone (lwpid)))
{
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "Cannot attach to lwp %d: "
- "thread is gone (%d: %s)\n",
- lwpid, err, safe_strerror (err));
- }
+ linux_nat_debug_printf
+ ("Cannot attach to lwp %d: thread is gone (%d: %s)",
+ lwpid, err, safe_strerror (err));
+
}
else
{
}
else
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "PTRACE_ATTACH %s, 0, 0 (OK)\n",
- target_pid_to_str (ptid));
+ linux_nat_debug_printf ("PTRACE_ATTACH %s, 0, 0 (OK)",
+ target_pid_to_str (ptid).c_str ());
lp = add_lwp (ptid);
/* Also add the LWP to gdb's thread list, in case a
matching libthread_db is not found (or the process uses
raw clone). */
- add_thread (lp->ptid);
- set_running (lp->ptid, 1);
- set_executing (lp->ptid, 1);
+ add_thread (linux_target, lp->ptid);
+ set_running (linux_target, lp->ptid, true);
+ set_executing (linux_target, lp->ptid, true);
}
return 1;
ptid_t ptid;
/* Make sure we report all signals during attach. */
- pass_signals (0, NULL);
+ pass_signals ({});
- TRY
+ try
{
inf_ptrace_target::attach (args, from_tty);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
pid_t pid = parse_pid_to_attach (args);
std::string reason = linux_ptrace_attach_fail_reason (pid);
if (!reason.empty ())
- throw_error (ex.error, "warning: %s\n%s", reason.c_str (), ex.message);
+ throw_error (ex.error, "warning: %s\n%s", reason.c_str (),
+ ex.what ());
else
- throw_error (ex.error, "%s", ex.message);
+ throw_error (ex.error, "%s", ex.what ());
}
- END_CATCH
/* The ptrace base target adds the main thread with (pid,0,0)
format. Decorate it with lwp info. */
ptid = ptid_t (inferior_ptid.pid (),
inferior_ptid.pid (),
0);
- thread_change_ptid (inferior_ptid, ptid);
+ thread_change_ptid (linux_target, inferior_ptid, ptid);
/* Add the initial process as the first LWP to the list. */
lp = add_initial_lwp (ptid);
/* Save the wait status to report later. */
lp->resumed = 1;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LNA: waitpid %ld, saving status %s\n",
- (long) lp->ptid.pid (), status_to_str (status));
+ linux_nat_debug_printf ("waitpid %ld, saving status %s",
+ (long) lp->ptid.pid (), status_to_str (status));
lp->status = status;
signo = gdb_signal_from_host (WSTOPSIG (lp->status));
else
{
- struct thread_info *tp = find_thread_ptid (lp->ptid);
+ struct thread_info *tp = find_thread_ptid (linux_target, lp->ptid);
if (target_is_non_stop_p () && !tp->executing)
{
}
else if (!target_is_non_stop_p ())
{
- struct target_waitstatus last;
ptid_t last_ptid;
+ process_stratum_target *last_target;
- get_last_target_status (&last_ptid, &last);
+ get_last_target_status (&last_target, &last_ptid, nullptr);
- if (lp->ptid.lwp () == last_ptid.lwp ())
+ if (last_target == linux_target
+ && lp->ptid.lwp () == last_ptid.lwp ())
signo = tp->suspend.stop_signal;
}
}
if (signo == GDB_SIGNAL_0)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "GPT: lwp %s has no pending signal\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("lwp %s has no pending signal",
+ target_pid_to_str (lp->ptid).c_str ());
}
else if (!signal_pass_state (signo))
{
- 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),
- gdb_signal_to_string (signo));
+ linux_nat_debug_printf
+ ("lwp %s had signal %s but it is in no pass state",
+ target_pid_to_str (lp->ptid).c_str (), gdb_signal_to_string (signo));
}
else
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "GPT: lwp %s has pending signal %s\n",
- target_pid_to_str (lp->ptid),
- gdb_signal_to_string (signo));
+ linux_nat_debug_printf ("lwp %s has pending signal %s",
+ target_pid_to_str (lp->ptid).c_str (),
+ gdb_signal_to_string (signo));
return gdb_signal_to_host (signo);
}
gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status));
- if (debug_linux_nat && lp->status)
- fprintf_unfiltered (gdb_stdlog, "DC: Pending %s for %s on detach.\n",
- strsignal (WSTOPSIG (lp->status)),
- target_pid_to_str (lp->ptid));
+ if (lp->status != 0)
+ linux_nat_debug_printf ("Pending %s for %s on detach.",
+ strsignal (WSTOPSIG (lp->status)),
+ target_pid_to_str (lp->ptid).c_str ());
/* If there is a pending SIGSTOP, get rid of it. */
if (lp->signalled)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "DC: Sending SIGCONT to %s\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Sending SIGCONT to %s",
+ target_pid_to_str (lp->ptid).c_str ());
kill_lwp (lwpid, SIGCONT);
lp->signalled = 0;
/* Preparing to resume may try to write registers, and fail if the
lwp is zombie. If that happens, ignore the error. We'll handle
it below, when detach fails with ESRCH. */
- TRY
+ try
{
linux_target->low_prepare_to_resume (lp);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (!check_ptrace_stopped_lwp_gone (lp))
- throw_exception (ex);
+ throw;
}
- END_CATCH
if (ptrace (PTRACE_DETACH, lwpid, 0, signo) < 0)
{
if (ret == -1)
{
warning (_("Couldn't reap LWP %d while detaching: %s"),
- lwpid, strerror (errno));
+ lwpid, safe_strerror (errno));
}
else if (!WIFEXITED (status) && !WIFSIGNALED (status))
{
}
else
{
- error (_("Can't detach %s: %s"), target_pid_to_str (lp->ptid),
+ error (_("Can't detach %s: %s"),
+ target_pid_to_str (lp->ptid).c_str (),
safe_strerror (save_errno));
}
}
- else if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "PTRACE_DETACH (%s, %s, 0) (OK)\n",
- target_pid_to_str (lp->ptid),
- strsignal (signo));
- }
+ else
+ linux_nat_debug_printf ("PTRACE_DETACH (%s, %s, 0) (OK)",
+ target_pid_to_str (lp->ptid).c_str (),
+ strsignal (signo));
delete_lwp (lp->ptid);
}
static int
-detach_callback (struct lwp_info *lp, void *data)
+detach_callback (struct lwp_info *lp)
{
/* We don't actually detach from the thread group leader just yet.
If the thread group exits, we must reap the zombie clone lwps
inferiors running. */
/* Stop all threads before detaching. ptrace requires that the
- thread is stopped to sucessfully detach. */
- iterate_over_lwps (ptid_t (pid), stop_callback, NULL);
+ thread is stopped to successfully detach. */
+ iterate_over_lwps (ptid_t (pid), stop_callback);
/* ... and wait until all of them have reported back that
they're no longer running. */
- iterate_over_lwps (ptid_t (pid), stop_wait_callback, NULL);
+ iterate_over_lwps (ptid_t (pid), stop_wait_callback);
- iterate_over_lwps (ptid_t (pid), detach_callback, NULL);
+ iterate_over_lwps (ptid_t (pid), detach_callback);
/* Only the initial process should be left right now. */
gdb_assert (num_lwps (pid) == 1);
handle the case of stepping a breakpoint instruction). */
if (step)
{
- struct regcache *regcache = get_thread_regcache (lp->ptid);
+ struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
lp->stop_pc = regcache_read_pc (regcache);
}
lp->stopped = 0;
lp->core = -1;
lp->stop_reason = TARGET_STOPPED_BY_NO_REASON;
- registers_changed_ptid (lp->ptid);
+ registers_changed_ptid (linux_target, lp->ptid);
}
/* Called when we try to resume a stopped LWP and that errors out. If
static void
linux_resume_one_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
{
- TRY
+ try
{
linux_resume_one_lwp_throw (lp, step, signo);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (!check_ptrace_stopped_lwp_gone (lp))
- throw_exception (ex);
+ throw;
}
- END_CATCH
}
/* Resume LP. */
{
if (lp->stopped)
{
- struct inferior *inf = find_inferior_ptid (lp->ptid);
+ struct inferior *inf = find_inferior_ptid (linux_target, lp->ptid);
if (inf->vfork_child != NULL)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RC: Not resuming %s (vfork parent)\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Not resuming %s (vfork parent)",
+ target_pid_to_str (lp->ptid).c_str ());
}
else if (!lwp_status_pending_p (lp))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "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");
+ linux_nat_debug_printf ("Resuming sibling %s, %s, %s",
+ target_pid_to_str (lp->ptid).c_str (),
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo))
+ : "0"),
+ step ? "step" : "resume");
linux_resume_one_lwp (lp, step, signo);
}
else
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RC: Not resuming sibling %s (has pending)\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Not resuming sibling %s (has pending)",
+ target_pid_to_str (lp->ptid).c_str ());
}
}
else
- {
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RC: Not resuming sibling %s (not stopped)\n",
- target_pid_to_str (lp->ptid));
- }
+ linux_nat_debug_printf ("Not resuming sibling %s (not stopped)",
+ target_pid_to_str (lp->ptid).c_str ());
}
/* Callback for iterate_over_lwps. If LWP is EXCEPT, do nothing.
Resume LWP with the last stop signal, if it is in pass state. */
static int
-linux_nat_resume_callback (struct lwp_info *lp, void *except)
+linux_nat_resume_callback (struct lwp_info *lp, struct lwp_info *except)
{
enum gdb_signal signo = GDB_SIGNAL_0;
{
struct thread_info *thread;
- thread = find_thread_ptid (lp->ptid);
+ thread = find_thread_ptid (linux_target, lp->ptid);
if (thread != NULL)
{
signo = thread->suspend.stop_signal;
}
static int
-resume_clear_callback (struct lwp_info *lp, void *data)
+resume_clear_callback (struct lwp_info *lp)
{
lp->resumed = 0;
lp->last_resume_kind = resume_stop;
}
static int
-resume_set_callback (struct lwp_info *lp, void *data)
+resume_set_callback (struct lwp_info *lp)
{
lp->resumed = 1;
lp->last_resume_kind = resume_continue;
struct lwp_info *lp;
int resume_many;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLR: Preparing to %s %s, %s, inferior_ptid %s\n",
- step ? "step" : "resume",
- target_pid_to_str (ptid),
- (signo != GDB_SIGNAL_0
- ? strsignal (gdb_signal_to_host (signo)) : "0"),
- target_pid_to_str (inferior_ptid));
+ linux_nat_debug_printf ("Preparing to %s %s, %s, inferior_ptid %s",
+ step ? "step" : "resume",
+ target_pid_to_str (ptid).c_str (),
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo)) : "0"),
+ target_pid_to_str (inferior_ptid).c_str ());
/* A specific PTID means `step only this process id'. */
resume_many = (minus_one_ptid == ptid
|| ptid.is_pid ());
- /* Mark the lwps we're resuming as resumed. */
- iterate_over_lwps (ptid, resume_set_callback, NULL);
+ /* Mark the lwps we're resuming as resumed and update their
+ last_resume_kind to resume_continue. */
+ iterate_over_lwps (ptid, resume_set_callback);
/* See if it's the current inferior that should be handled
specially. */
&& WSTOPSIG (lp->status)
&& sigismember (&pass_mask, WSTOPSIG (lp->status)))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLR: Not short circuiting for ignored "
- "status 0x%x\n", lp->status);
+ linux_nat_debug_printf
+ ("Not short circuiting for ignored status 0x%x", lp->status);
/* FIXME: What should we do if we are supposed to continue
this thread with a signal? */
this thread with a signal? */
gdb_assert (signo == GDB_SIGNAL_0);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLR: Short circuiting for status 0x%x\n",
- lp->status);
+ linux_nat_debug_printf ("Short circuiting for status 0x%x",
+ lp->status);
if (target_can_async_p ())
{
}
if (resume_many)
- iterate_over_lwps (ptid, linux_nat_resume_callback, lp);
+ iterate_over_lwps (ptid, [=] (struct lwp_info *info)
+ {
+ return linux_nat_resume_callback (info, lp);
+ });
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLR: %s %s, %s (resume event thread)\n",
- step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
- target_pid_to_str (lp->ptid),
- (signo != GDB_SIGNAL_0
- ? strsignal (gdb_signal_to_host (signo)) : "0"));
+ linux_nat_debug_printf ("%s %s, %s (resume event thread)",
+ step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+ target_pid_to_str (lp->ptid).c_str (),
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo)) : "0"));
linux_resume_one_lwp (lp, step, signo);
{
struct target_waitstatus *ourstatus = &lp->waitstatus;
struct gdbarch *gdbarch = target_thread_architecture (lp->ptid);
- thread_info *thread = find_thread_ptid (lp->ptid);
+ thread_info *thread = find_thread_ptid (linux_target, lp->ptid);
int syscall_number = (int) gdbarch_get_syscall_number (gdbarch, thread);
if (stopping)
actually get to execute. It seems it would be even more
confusing to the user. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHST: ignoring syscall %d "
- "for LWP %ld (stopping threads), "
- "resuming with PTRACE_CONT for SIGSTOP\n",
- syscall_number,
- lp->ptid.lwp ());
+ linux_nat_debug_printf
+ ("ignoring syscall %d for LWP %ld (stopping threads), resuming with "
+ "PTRACE_CONT for SIGSTOP", syscall_number, lp->ptid.lwp ());
lp->syscall_state = TARGET_WAITKIND_IGNORE;
ptrace (PTRACE_CONT, lp->ptid.lwp (), 0, 0);
ourstatus->kind = lp->syscall_state;
ourstatus->value.syscall_number = syscall_number;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHST: stopping for %s of syscall %d"
- " for LWP %ld\n",
- lp->syscall_state
- == TARGET_WAITKIND_SYSCALL_ENTRY
- ? "entry" : "return",
- syscall_number,
- lp->ptid.lwp ());
+ linux_nat_debug_printf
+ ("stopping for %s of syscall %d for LWP %ld",
+ (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
+ ? "entry" : "return"), syscall_number, lp->ptid.lwp ());
+
return 0;
}
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHST: ignoring %s of syscall %d "
- "for LWP %ld\n",
- lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
- ? "entry" : "return",
- syscall_number,
- lp->ptid.lwp ());
+ linux_nat_debug_printf
+ ("ignoring %s of syscall %d for LWP %ld",
+ (lp->syscall_state == TARGET_WAITKIND_SYSCALL_ENTRY
+ ? "entry" : "return"), syscall_number, lp->ptid.lwp ());
}
else
{
The points above mean that the next resume, be it PT_STEP or
PT_CONTINUE, can not trigger a syscall trace event. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHST: caught syscall event "
- "with no syscall catchpoints."
- " %d for LWP %ld, ignoring\n",
- syscall_number,
- lp->ptid.lwp ());
+ linux_nat_debug_printf
+ ("caught syscall event with no syscall catchpoints. %d for LWP %ld, "
+ "ignoring", syscall_number, lp->ptid.lwp ());
lp->syscall_state = TARGET_WAITKIND_IGNORE;
}
inferior. */
linux_target->low_new_fork (lp, new_pid);
}
+ else if (event == PTRACE_EVENT_CLONE)
+ {
+ linux_target->low_new_clone (lp, new_pid);
+ }
if (event == PTRACE_EVENT_FORK
&& linux_fork_checkpointing_p (lp->ptid.pid ()))
ourstatus->kind = TARGET_WAITKIND_IGNORE;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHEW: Got clone event "
- "from LWP %d, new child is LWP %ld\n",
- pid, new_pid);
+ linux_nat_debug_printf
+ ("Got clone event from LWP %d, new child is LWP %ld", pid, new_pid);
new_lp = add_lwp (ptid_t (lp->ptid.pid (), new_pid, 0));
new_lp->stopped = 1;
/* The process is not using thread_db. Add the LWP to
GDB's list. */
target_post_attach (new_lp->ptid.lwp ());
- add_thread (new_lp->ptid);
+ add_thread (linux_target, new_lp->ptid);
}
/* Even if we're stopping the thread for some reason
internal to this module, from the perspective of infrun
and the user/frontend, this new thread is running until
it next reports a stop. */
- set_running (new_lp->ptid, 1);
- set_executing (new_lp->ptid, 1);
+ set_running (linux_target, new_lp->ptid, true);
+ set_executing (linux_target, new_lp->ptid, true);
if (WSTOPSIG (status) != SIGSTOP)
{
gdb_assert (new_lp->status == 0);
/* Save the wait status to report later. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHEW: waitpid of new LWP %ld, "
- "saving status %s\n",
- (long) new_lp->ptid.lwp (),
- status_to_str (status));
+ linux_nat_debug_printf
+ ("waitpid of new LWP %ld, saving status %s",
+ (long) new_lp->ptid.lwp (), status_to_str (status));
new_lp->status = status;
}
else if (report_thread_events)
if (event == PTRACE_EVENT_EXEC)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHEW: Got exec event from LWP %ld\n",
- lp->ptid.lwp ());
+ linux_nat_debug_printf ("Got exec event from LWP %ld", lp->ptid.lwp ());
ourstatus->kind = TARGET_WAITKIND_EXECD;
ourstatus->value.execd_pathname
{
if (current_inferior ()->waiting_for_vfork_done)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHEW: Got expected PTRACE_EVENT_"
- "VFORK_DONE from LWP %ld: stopping\n",
- lp->ptid.lwp ());
+ linux_nat_debug_printf
+ ("Got expected PTRACE_EVENT_VFORK_DONE from LWP %ld: stopping",
+ lp->ptid.lwp ());
ourstatus->kind = TARGET_WAITKIND_VFORK_DONE;
return 0;
}
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHEW: Got PTRACE_EVENT_VFORK_DONE "
- "from LWP %ld: ignoring\n",
- lp->ptid.lwp ());
+ linux_nat_debug_printf
+ ("Got PTRACE_EVENT_VFORK_DONE from LWP %ld: ignoring", lp->ptid.lwp ());
+
return 1;
}
static void
wait_for_signal ()
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "linux-nat: about to sigsuspend\n");
+ linux_nat_debug_printf ("about to sigsuspend");
sigsuspend (&suspend_mask);
/* If the quit flag is set, it means that the user pressed Ctrl-C
won't get an exit event. See comments on exec events at
the top of the file. */
thread_dead = 1;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "WL: %s vanished.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s vanished.",
+ target_pid_to_str (lp->ptid).c_str ());
}
if (pid != 0)
break;
&& linux_proc_pid_is_zombie (lp->ptid.lwp ()))
{
thread_dead = 1;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "WL: Thread group leader %s vanished.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Thread group leader %s vanished.",
+ target_pid_to_str (lp->ptid).c_str ());
break;
}
{
gdb_assert (pid == lp->ptid.lwp ());
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "WL: waitpid %s received %s\n",
- target_pid_to_str (lp->ptid),
+ linux_nat_debug_printf ("waitpid %s received %s",
+ target_pid_to_str (lp->ptid).c_str (),
status_to_str (status));
- }
/* Check if the thread has exited. */
if (WIFEXITED (status) || WIFSIGNALED (status))
if (report_thread_events
|| lp->ptid.pid () == lp->ptid.lwp ())
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "WL: LWP %d exited.\n",
- lp->ptid.pid ());
+ linux_nat_debug_printf ("LWP %d exited.", lp->ptid.pid ());
/* If this is the leader exiting, it means the whole
process is gone. Store the status to report to the
}
thread_dead = 1;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "WL: %s exited.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s exited.",
+ target_pid_to_str (lp->ptid).c_str ());
}
}
if (lp->must_set_ptrace_flags)
{
- struct inferior *inf = find_inferior_pid (lp->ptid.pid ());
+ inferior *inf = find_inferior_pid (linux_target, lp->ptid.pid ());
int options = linux_nat_ptrace_options (inf->attach_flag);
linux_enable_event_reporting (lp->ptid.lwp (), options);
if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP
&& linux_is_extended_waitstatus (status))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "WL: Handling extended status 0x%06x\n",
- status);
+ linux_nat_debug_printf ("Handling extended status 0x%06x", status);
linux_handle_extended_wait (lp, status);
return 0;
}
/* Send a SIGSTOP to LP. */
static int
-stop_callback (struct lwp_info *lp, void *data)
+stop_callback (struct lwp_info *lp)
{
if (!lp->stopped && !lp->signalled)
{
int ret;
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "SC: kill %s **<SIGSTOP>**\n",
- target_pid_to_str (lp->ptid));
- }
+ linux_nat_debug_printf ("kill %s **<SIGSTOP>**",
+ target_pid_to_str (lp->ptid).c_str ());
+
errno = 0;
ret = kill_lwp (lp->ptid.lwp (), SIGSTOP);
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "SC: lwp kill %d %s\n",
- ret,
+ linux_nat_debug_printf ("lwp kill %d %s", ret,
errno ? safe_strerror (errno) : "ERRNO-OK");
- }
lp->signalled = 1;
gdb_assert (lp->status == 0);
void
linux_stop_lwp (struct lwp_info *lwp)
{
- stop_callback (lwp, NULL);
+ stop_callback (lwp);
}
/* See linux-nat.h */
linux_stop_and_wait_all_lwps (void)
{
/* Stop all LWP's ... */
- iterate_over_lwps (minus_one_ptid, stop_callback, NULL);
+ iterate_over_lwps (minus_one_ptid, stop_callback);
/* ... and wait until all of them have reported back that
they're no longer running. */
- iterate_over_lwps (minus_one_ptid, stop_wait_callback, NULL);
+ iterate_over_lwps (minus_one_ptid, stop_wait_callback);
}
/* See linux-nat.h */
linux_unstop_all_lwps (void)
{
iterate_over_lwps (minus_one_ptid,
- resume_stopped_resumed_lwps, &minus_one_ptid);
+ [] (struct lwp_info *info)
+ {
+ return resume_stopped_resumed_lwps (info, minus_one_ptid);
+ });
}
/* Return non-zero if LWP PID has a pending SIGINT. */
/* Set a flag in LP indicating that we should ignore its next SIGINT. */
static int
-set_ignore_sigint (struct lwp_info *lp, void *data)
+set_ignore_sigint (struct lwp_info *lp)
{
/* If a thread has a pending SIGINT, consume it; otherwise, set a
flag to consume the next one. */
if (!linux_nat_has_pending_sigint (lp->ptid.lwp ()))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "MCIS: Clearing bogus flag for %s\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Clearing bogus flag for %s",
+ target_pid_to_str (lp->ptid).c_str ());
lp->ignore_sigint = 0;
}
}
/* Wait until LP is stopped. */
static int
-stop_wait_callback (struct lwp_info *lp, void *data)
+stop_wait_callback (struct lwp_info *lp)
{
- struct inferior *inf = find_inferior_ptid (lp->ptid);
+ inferior *inf = find_inferior_ptid (linux_target, lp->ptid);
/* If this is a vfork parent, bail out, it is not going to report
any SIGSTOP until the vfork is done with. */
errno = 0;
ptrace (PTRACE_CONT, lp->ptid.lwp (), 0, 0);
lp->stopped = 0;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "PTRACE_CONT %s, 0, 0 (%s) "
- "(discarding SIGINT)\n",
- target_pid_to_str (lp->ptid),
- errno ? safe_strerror (errno) : "OK");
-
- return stop_wait_callback (lp, NULL);
+ linux_nat_debug_printf
+ ("PTRACE_CONT %s, 0, 0 (%s) (discarding SIGINT)",
+ target_pid_to_str (lp->ptid).c_str (),
+ errno ? safe_strerror (errno) : "OK");
+
+ return stop_wait_callback (lp);
}
maybe_clear_ignore_sigint (lp);
{
/* The thread was stopped with a signal other than SIGSTOP. */
- 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));
+ linux_nat_debug_printf ("Pending event %s in %s",
+ status_to_str ((int) status),
+ target_pid_to_str (lp->ptid).c_str ());
/* Save the sigtrap event. */
lp->status = status;
{
/* We caught the SIGSTOP that we intended to catch. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SWC: Expected SIGSTOP caught for %s.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Expected SIGSTOP caught for %s.",
+ target_pid_to_str (lp->ptid).c_str ());
lp->signalled = 0;
caused the stop became uninteresting. */
static int
-status_callback (struct lwp_info *lp, void *data)
+status_callback (struct lwp_info *lp)
{
/* Only report a pending wait status if we pretend that this has
indeed been resumed. */
if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
|| lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
{
- struct regcache *regcache = get_thread_regcache (lp->ptid);
+ struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
CORE_ADDR pc;
int discard = 0;
if (pc != lp->stop_pc)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SC: PC of %s changed. was=%s, now=%s\n",
- target_pid_to_str (lp->ptid),
- paddress (target_gdbarch (), lp->stop_pc),
- paddress (target_gdbarch (), pc));
+ linux_nat_debug_printf ("PC of %s changed. was=%s, now=%s",
+ target_pid_to_str (lp->ptid).c_str (),
+ paddress (target_gdbarch (), lp->stop_pc),
+ paddress (target_gdbarch (), pc));
discard = 1;
}
#if !USE_SIGTRAP_SIGINFO
else if (!breakpoint_inserted_here_p (regcache->aspace (), pc))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SC: previous breakpoint of %s, at %s gone\n",
- target_pid_to_str (lp->ptid),
- paddress (target_gdbarch (), lp->stop_pc));
+ linux_nat_debug_printf ("previous breakpoint of %s, at %s gone",
+ target_pid_to_str (lp->ptid).c_str (),
+ paddress (target_gdbarch (), lp->stop_pc));
discard = 1;
}
if (discard)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SC: pending event of %s cancelled.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("pending event of %s cancelled.",
+ target_pid_to_str (lp->ptid).c_str ());
lp->status = 0;
linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
/* Count the LWP's that have had events. */
static int
-count_events_callback (struct lwp_info *lp, void *data)
+count_events_callback (struct lwp_info *lp, int *count)
{
- int *count = (int *) data;
-
gdb_assert (count != NULL);
/* Select only resumed LWPs that have an event pending. */
/* Select the LWP (if any) that is currently being single-stepped. */
static int
-select_singlestep_lwp_callback (struct lwp_info *lp, void *data)
+select_singlestep_lwp_callback (struct lwp_info *lp)
{
if (lp->last_resume_kind == resume_step
&& lp->status != 0)
/* Select the Nth LWP that has had an event. */
static int
-select_event_lwp_callback (struct lwp_info *lp, void *data)
+select_event_lwp_callback (struct lwp_info *lp, int *selector)
{
- int *selector = (int *) data;
-
gdb_assert (selector != NULL);
/* Select only resumed LWPs that have an event pending. */
if (!linux_target->low_status_is_event (lp->status))
return;
- regcache = get_thread_regcache (lp->ptid);
+ regcache = get_thread_regcache (linux_target, lp->ptid);
gdbarch = regcache->arch ();
pc = regcache_read_pc (regcache);
{
/* If we determine the LWP stopped for a SW breakpoint,
trust it. Particularly don't check watchpoint
- registers, because at least on s390, we'd find
+ registers, because, at least on s390, we'd find
stopped-by-watchpoint as long as there's a watchpoint
set. */
lp->stop_reason = TARGET_STOPPED_BY_SW_BREAKPOINT;
}
else if (siginfo.si_code == TRAP_TRACE)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "CSBB: %s stopped by trace\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s stopped by trace",
+ target_pid_to_str (lp->ptid).c_str ());
/* We may have single stepped an instruction that
triggered a watchpoint. In that case, on some
if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "CSBB: %s stopped by software breakpoint\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s stopped by software breakpoint",
+ target_pid_to_str (lp->ptid).c_str ());
/* Back up the PC if necessary. */
if (pc != sw_bp_pc)
}
else if (lp->stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "CSBB: %s stopped by hardware breakpoint\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s stopped by hardware breakpoint",
+ target_pid_to_str (lp->ptid).c_str ());
}
else if (lp->stop_reason == TARGET_STOPPED_BY_WATCHPOINT)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "CSBB: %s stopped by hardware watchpoint\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s stopped by hardware watchpoint",
+ target_pid_to_str (lp->ptid).c_str ());
}
lp->stop_pc = pc;
signal. */
if (!target_is_non_stop_p ())
{
- event_lp = iterate_over_lwps (filter,
- select_singlestep_lwp_callback, NULL);
+ event_lp = iterate_over_lwps (filter, select_singlestep_lwp_callback);
if (event_lp != NULL)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "SEL: Select single-step %s\n",
- target_pid_to_str (event_lp->ptid));
+ linux_nat_debug_printf ("Select single-step %s",
+ target_pid_to_str (event_lp->ptid).c_str ());
}
}
/* Pick one at random, out of those which have had events. */
/* First see how many events we have. */
- iterate_over_lwps (filter, count_events_callback, &num_events);
+ iterate_over_lwps (filter,
+ [&] (struct lwp_info *info)
+ {
+ return count_events_callback (info, &num_events);
+ });
gdb_assert (num_events > 0);
/* Now randomly pick a LWP out of those that have had
random_selector = (int)
((num_events * (double) rand ()) / (RAND_MAX + 1.0));
- if (debug_linux_nat && num_events > 1)
- fprintf_unfiltered (gdb_stdlog,
- "SEL: Found %d events, selecting #%d\n",
- num_events, random_selector);
+ if (num_events > 1)
+ linux_nat_debug_printf ("Found %d events, selecting #%d",
+ num_events, random_selector);
- event_lp = iterate_over_lwps (filter,
- select_event_lwp_callback,
- &random_selector);
+ event_lp
+ = (iterate_over_lwps
+ (filter,
+ [&] (struct lwp_info *info)
+ {
+ return select_event_lwp_callback (info,
+ &random_selector);
+ }));
}
if (event_lp != NULL)
/* Return non-zero if LP has been resumed. */
static int
-resumed_callback (struct lwp_info *lp, void *data)
+resumed_callback (struct lwp_info *lp)
{
return lp->resumed;
}
/* Check if we should go on and pass this event to common code.
- Return the affected lwp if we are, or NULL otherwise. */
+ Return the affected lwp if we should, or NULL otherwise. */
static struct lwp_info *
linux_nat_filter_event (int lwpid, int status)
&& (WSTOPSIG (status) == SIGTRAP && event == PTRACE_EVENT_EXEC))
{
/* A multi-thread exec after we had seen the leader exiting. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: Re-adding thread group leader LWP %d.\n",
- lwpid);
+ linux_nat_debug_printf ("Re-adding thread group leader LWP %d.", lwpid);
lp = add_lwp (ptid_t (lwpid, lwpid, 0));
lp->stopped = 1;
lp->resumed = 1;
- add_thread (lp->ptid);
+ add_thread (linux_target, lp->ptid);
}
if (WIFSTOPPED (status) && !lp)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LHEW: saving LWP %ld status %s in stopped_pids list\n",
- (long) lwpid, status_to_str (status));
+ linux_nat_debug_printf ("saving LWP %ld status %s in stopped_pids list",
+ (long) lwpid, status_to_str (status));
add_to_pid_list (&stopped_pids, lwpid, status);
return NULL;
}
if (WIFSTOPPED (status) && lp->must_set_ptrace_flags)
{
- struct inferior *inf = find_inferior_pid (lp->ptid.pid ());
+ inferior *inf = find_inferior_pid (linux_target, lp->ptid.pid ());
int options = linux_nat_ptrace_options (inf->attach_flag);
linux_enable_event_reporting (lp->ptid.lwp (), options);
if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP
&& linux_is_extended_waitstatus (status))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: Handling extended status 0x%06x\n",
- status);
+ linux_nat_debug_printf ("Handling extended status 0x%06x", status);
+
if (linux_handle_extended_wait (lp, status))
return NULL;
}
if (!report_thread_events
&& num_lwps (lp->ptid.pid ()) > 1)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: %s exited.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s exited.",
+ target_pid_to_str (lp->ptid).c_str ());
/* If there is at least one more LWP, then the exit signal
was not the end of the debugged application and should be
exit, if e.g., some other thread brings down the whole
process (calls `exit'). So don't assert that the lwp is
resumed. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LWP %ld exited (resumed=%d)\n",
- lp->ptid.lwp (), lp->resumed);
+ linux_nat_debug_printf ("LWP %ld exited (resumed=%d)",
+ lp->ptid.lwp (), lp->resumed);
/* Dead LWP's aren't expected to reported a pending sigstop. */
lp->signalled = 0;
if (lp->last_resume_kind == resume_stop)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: resume_stop SIGSTOP caught for %s.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("resume_stop SIGSTOP caught for %s.",
+ target_pid_to_str (lp->ptid).c_str ());
}
else
{
/* This is a delayed SIGSTOP. Filter out the event. */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: %s %s, 0, 0 (discard delayed SIGSTOP)\n",
- lp->step ?
- "PTRACE_SINGLESTEP" : "PTRACE_CONT",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf
+ ("%s %s, 0, 0 (discard delayed SIGSTOP)",
+ lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+ target_pid_to_str (lp->ptid).c_str ());
linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
gdb_assert (lp->resumed);
if (lp->ignore_sigint
&& WIFSTOPPED (status) && WSTOPSIG (status) == SIGINT)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: Delayed SIGINT caught for %s.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Delayed SIGINT caught for %s.",
+ target_pid_to_str (lp->ptid).c_str ());
/* This is a delayed SIGINT. */
lp->ignore_sigint = 0;
linux_resume_one_lwp (lp, lp->step, GDB_SIGNAL_0);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: %s %s, 0, 0 (discard SIGINT)\n",
- lp->step ?
- "PTRACE_SINGLESTEP" : "PTRACE_CONT",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("%s %s, 0, 0 (discard SIGINT)",
+ lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+ target_pid_to_str (lp->ptid).c_str ());
gdb_assert (lp->resumed);
/* Discard the event. */
/* Don't report signals that GDB isn't interested in, such as
signals that are neither printed nor stopped upon. Stopping all
- threads can be a bit time-consuming so if we want decent
+ threads can be a bit time-consuming, so if we want decent
performance with heavily multi-threaded programs, especially when
they're using a high frequency timer, we'd better avoid it if we
can. */
will receive it - unless they're using CLONE_THREAD to
share signals. Since we only want to report it once, we
mark it as ignored for all LWPs except this one. */
- iterate_over_lwps (ptid_t (lp->ptid.pid ()),
- set_ignore_sigint, NULL);
+ iterate_over_lwps (ptid_t (lp->ptid.pid ()), set_ignore_sigint);
lp->ignore_sigint = 0;
}
else
/* When using hardware single-step, we need to report every signal.
Otherwise, signals in pass_mask may be short-circuited
- except signals that might be caused by a breakpoint. */
+ except signals that might be caused by a breakpoint, or SIGSTOP
+ if we sent the SIGSTOP and are waiting for it to arrive. */
if (!lp->step
&& WSTOPSIG (status) && sigismember (&pass_mask, WSTOPSIG (status))
+ && (WSTOPSIG (status) != SIGSTOP
+ || !find_thread_ptid (linux_target, lp->ptid)->stop_requested)
&& !linux_wstatus_maybe_breakpoint (status))
{
linux_resume_one_lwp (lp, lp->step, signo);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: %s %s, %s (preempt 'handle')\n",
- lp->step ?
- "PTRACE_SINGLESTEP" : "PTRACE_CONT",
- target_pid_to_str (lp->ptid),
- (signo != GDB_SIGNAL_0
- ? strsignal (gdb_signal_to_host (signo))
- : "0"));
+ linux_nat_debug_printf
+ ("%s %s, %s (preempt 'handle')",
+ lp->step ? "PTRACE_SINGLESTEP" : "PTRACE_CONT",
+ target_pid_to_str (lp->ptid).c_str (),
+ (signo != GDB_SIGNAL_0
+ ? strsignal (gdb_signal_to_host (signo)) : "0"));
return NULL;
}
}
static void
check_zombie_leaders (void)
{
- struct inferior *inf;
-
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_inferiors ())
{
struct lwp_info *leader_lp;
&& num_lwps (inf->pid) > 1
&& linux_proc_pid_is_zombie (inf->pid))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "CZL: Thread group leader %d zombie "
- "(it exited, or another thread execd).\n",
- inf->pid);
+ linux_nat_debug_printf ("Thread group leader %d zombie "
+ "(it exited, or another thread execd).",
+ inf->pid);
/* A leader zombie can mean one of two things:
previous leader did exit voluntarily before some other
thread execs). */
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "CZL: Thread group leader %d vanished.\n",
- inf->pid);
+ linux_nat_debug_printf ("Thread group leader %d vanished.", inf->pid);
exit_lwp (leader_lp);
}
}
struct lwp_info *lp;
int status;
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "LLW: enter\n");
+ linux_nat_debug_printf ("enter");
/* The first time we get here after starting a new inferior, we may
not have added it to the LWP list yet - this is the earliest
if (inferior_ptid.is_pid ())
{
/* Upgrade the main thread's ptid. */
- thread_change_ptid (inferior_ptid,
+ thread_change_ptid (linux_target, inferior_ptid,
ptid_t (inferior_ptid.pid (),
inferior_ptid.pid (), 0));
block_child_signals (&prev_mask);
/* First check if there is a LWP with a wait status pending. */
- lp = iterate_over_lwps (ptid, status_callback, NULL);
+ lp = iterate_over_lwps (ptid, status_callback);
if (lp != NULL)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: Using pending wait status %s for %s.\n",
- status_to_str (lp->status),
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("Using pending wait status %s for %s.",
+ status_to_str (lp->status),
+ target_pid_to_str (lp->ptid).c_str ());
}
/* But if we don't find a pending event, we'll have to wait. Always
- If the thread group leader exits while other threads in the
thread group still exist, waitpid(TGID, ...) hangs. That
waitpid won't return an exit status until the other threads
- in the group are reapped.
+ in the group are reaped.
- When a non-leader thread execs, that thread just vanishes
without reporting an exit (so we'd hang if we waited for it
errno = 0;
lwpid = my_waitpid (-1, &status, __WALL | WNOHANG);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LNW: waitpid(-1, ...) returned %d, %s\n",
- lwpid, errno ? safe_strerror (errno) : "ERRNO-OK");
+ linux_nat_debug_printf ("waitpid(-1, ...) returned %d, %s",
+ lwpid,
+ errno ? safe_strerror (errno) : "ERRNO-OK");
if (lwpid > 0)
{
- if (debug_linux_nat)
- {
- fprintf_unfiltered (gdb_stdlog,
- "LLW: waitpid %ld received %s\n",
+ linux_nat_debug_printf ("waitpid %ld received %s",
(long) lwpid, status_to_str (status));
- }
linux_nat_filter_event (lwpid, status);
/* Retry until nothing comes out of waitpid. A single
/* Now that we've pulled all events out of the kernel, resume
LWPs that don't have an interesting event to report. */
iterate_over_lwps (minus_one_ptid,
- resume_stopped_resumed_lwps, &minus_one_ptid);
+ [] (struct lwp_info *info)
+ {
+ return resume_stopped_resumed_lwps (info, minus_one_ptid);
+ });
/* ... and find an LWP with a status to report to the core, if
any. */
- lp = iterate_over_lwps (ptid, status_callback, NULL);
+ lp = iterate_over_lwps (ptid, status_callback);
if (lp != NULL)
break;
/* If there are no resumed children left, bail. We'd be stuck
forever in the sigsuspend call below otherwise. */
- if (iterate_over_lwps (ptid, resumed_callback, NULL) == NULL)
+ if (iterate_over_lwps (ptid, resumed_callback) == NULL)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "LLW: exit (no resumed LWP)\n");
+ linux_nat_debug_printf ("exit (no resumed LWP)");
ourstatus->kind = TARGET_WAITKIND_NO_RESUMED;
if (target_options & TARGET_WNOHANG)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "LLW: exit (ignore)\n");
+ linux_nat_debug_printf ("exit (ignore)");
ourstatus->kind = TARGET_WAITKIND_IGNORE;
restore_child_signals_mask (&prev_mask);
if (!target_is_non_stop_p ())
{
/* Now stop all other LWP's ... */
- iterate_over_lwps (minus_one_ptid, stop_callback, NULL);
+ iterate_over_lwps (minus_one_ptid, stop_callback);
/* ... and wait until all of them have reported back that
they're no longer running. */
- iterate_over_lwps (minus_one_ptid, stop_wait_callback, NULL);
+ iterate_over_lwps (minus_one_ptid, stop_wait_callback);
}
/* If we're not waiting for a specific LWP, choose an event LWP from
if (lp->stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
&& !USE_SIGTRAP_SIGINFO)
{
- struct regcache *regcache = get_thread_regcache (lp->ptid);
+ struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
struct gdbarch *gdbarch = regcache->arch ();
int decr_pc = gdbarch_decr_pc_after_break (gdbarch);
{
/* In all-stop, from the core's perspective, all LWPs are now
stopped until a new resume action is sent over. */
- iterate_over_lwps (minus_one_ptid, resume_clear_callback, NULL);
+ iterate_over_lwps (minus_one_ptid, resume_clear_callback);
}
else
{
- resume_clear_callback (lp, NULL);
+ resume_clear_callback (lp);
}
if (linux_target->low_status_is_event (status))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LLW: trap ptid is %s.\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("trap ptid is %s.",
+ target_pid_to_str (lp->ptid).c_str ());
}
if (lp->waitstatus.kind != TARGET_WAITKIND_IGNORE)
else
store_waitstatus (ourstatus, status);
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog, "LLW: exit\n");
+ linux_nat_debug_printf ("exit");
restore_child_signals_mask (&prev_mask);
to report, but are resumed from the core's perspective. */
static int
-resume_stopped_resumed_lwps (struct lwp_info *lp, void *data)
+resume_stopped_resumed_lwps (struct lwp_info *lp, const ptid_t wait_ptid)
{
- ptid_t *wait_ptid_p = (ptid_t *) data;
-
if (!lp->stopped)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RSRL: NOT resuming LWP %s, not stopped\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("NOT resuming LWP %s, not stopped",
+ target_pid_to_str (lp->ptid).c_str ());
}
else if (!lp->resumed)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RSRL: NOT resuming LWP %s, not resumed\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("NOT resuming LWP %s, not resumed",
+ target_pid_to_str (lp->ptid).c_str ());
}
else if (lwp_status_pending_p (lp))
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RSRL: NOT resuming LWP %s, has pending status\n",
- target_pid_to_str (lp->ptid));
+ linux_nat_debug_printf ("NOT resuming LWP %s, has pending status",
+ target_pid_to_str (lp->ptid).c_str ());
}
else
{
- struct regcache *regcache = get_thread_regcache (lp->ptid);
+ struct regcache *regcache = get_thread_regcache (linux_target, lp->ptid);
struct gdbarch *gdbarch = regcache->arch ();
- TRY
+ try
{
CORE_ADDR pc = regcache_read_pc (regcache);
int leave_stopped = 0;
/* Don't bother if there's a breakpoint at PC that we'd hit
immediately, and we're not waiting for this LWP. */
- if (!lp->ptid.matches (*wait_ptid_p))
+ if (!lp->ptid.matches (wait_ptid))
{
if (breakpoint_inserted_here_p (regcache->aspace (), pc))
leave_stopped = 1;
if (!leave_stopped)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "RSRL: resuming stopped-resumed LWP %s at "
- "%s: step=%d\n",
- target_pid_to_str (lp->ptid),
- paddress (gdbarch, pc),
- lp->step);
+ linux_nat_debug_printf
+ ("resuming stopped-resumed LWP %s at %s: step=%d",
+ target_pid_to_str (lp->ptid).c_str (), paddress (gdbarch, pc),
+ lp->step);
linux_resume_one_lwp_throw (lp, lp->step, GDB_SIGNAL_0);
}
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
if (!check_ptrace_stopped_lwp_gone (lp))
- throw_exception (ex);
+ throw;
}
- END_CATCH
}
return 0;
{
ptid_t event_ptid;
- if (debug_linux_nat)
- {
- std::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.c_str ());
- }
+ linux_nat_debug_printf ("[%s], [%s]", target_pid_to_str (ptid).c_str (),
+ target_options_to_string (target_options).c_str ());
/* Flush the async file first. */
if (target_is_async_p ())
meanwhile the event became uninteresting. Don't bother resuming
LWPs we're not going to wait for if they'd stop immediately. */
if (target_is_non_stop_p ())
- iterate_over_lwps (minus_one_ptid, resume_stopped_resumed_lwps, &ptid);
+ iterate_over_lwps (minus_one_ptid,
+ [=] (struct lwp_info *info)
+ {
+ return resume_stopped_resumed_lwps (info, ptid);
+ });
event_ptid = linux_nat_wait_1 (ptid, ourstatus, target_options);
errno = 0;
kill_lwp (pid, SIGKILL);
+
if (debug_linux_nat)
{
int save_errno = errno;
- fprintf_unfiltered (gdb_stdlog,
- "KC: kill (SIGKILL) %ld, 0, 0 (%s)\n", (long) pid,
- save_errno ? safe_strerror (save_errno) : "OK");
+ linux_nat_debug_printf
+ ("kill (SIGKILL) %ld, 0, 0 (%s)", (long) pid,
+ save_errno != 0 ? safe_strerror (save_errno) : "OK");
}
/* Some kernels ignore even SIGKILL for processes under ptrace. */
{
int save_errno = errno;
- fprintf_unfiltered (gdb_stdlog,
- "KC: PTRACE_KILL %ld, 0, 0 (%s)\n", (long) pid,
- save_errno ? safe_strerror (save_errno) : "OK");
+ linux_nat_debug_printf
+ ("PTRACE_KILL %ld, 0, 0 (%s)", (long) pid,
+ save_errno ? safe_strerror (save_errno) : "OK");
}
}
res = my_waitpid (pid, NULL, __WALL);
if (res != (pid_t) -1)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "KWC: wait %ld received unknown.\n",
- (long) pid);
+ linux_nat_debug_printf ("wait %ld received unknown.", (long) pid);
+
/* The Linux kernel sometimes fails to kill a thread
completely after PTRACE_KILL; that goes from the stop
point in do_fork out to the one in get_signal_to_deliver
/* Callback for iterate_over_lwps. */
static int
-kill_callback (struct lwp_info *lp, void *data)
+kill_callback (struct lwp_info *lp)
{
kill_one_lwp (lp->ptid.lwp ());
return 0;
/* Callback for iterate_over_lwps. */
static int
-kill_wait_callback (struct lwp_info *lp, void *data)
+kill_wait_callback (struct lwp_info *lp)
{
kill_wait_one_lwp (lp->ptid.lwp ());
return 0;
static void
kill_unfollowed_fork_children (struct inferior *inf)
{
- struct thread_info *thread;
+ for (thread_info *thread : inf->non_exited_threads ())
+ {
+ struct target_waitstatus *ws = &thread->pending_follow;
- ALL_NON_EXITED_THREADS (thread)
- if (thread->inf == inf)
- {
- struct target_waitstatus *ws = &thread->pending_follow;
-
- if (ws->kind == TARGET_WAITKIND_FORKED
- || ws->kind == TARGET_WAITKIND_VFORKED)
- {
- ptid_t child_ptid = ws->value.related_pid;
- int child_pid = child_ptid.pid ();
- int child_lwp = child_ptid.lwp ();
-
- kill_one_lwp (child_lwp);
- kill_wait_one_lwp (child_lwp);
-
- /* Let the arch-specific native code know this process is
- gone. */
- linux_target->low_forget_process (child_pid);
- }
- }
+ if (ws->kind == TARGET_WAITKIND_FORKED
+ || ws->kind == TARGET_WAITKIND_VFORKED)
+ {
+ ptid_t child_ptid = ws->value.related_pid;
+ int child_pid = child_ptid.pid ();
+ int child_lwp = child_ptid.lwp ();
+
+ kill_one_lwp (child_lwp);
+ kill_wait_one_lwp (child_lwp);
+
+ /* Let the arch-specific native code know this process is
+ gone. */
+ linux_target->low_forget_process (child_pid);
+ }
+ }
}
void
ptid_t ptid = ptid_t (inferior_ptid.pid ());
/* 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);
+ that the thread is stopped to successfully PTRACE_KILL. */
+ iterate_over_lwps (ptid, stop_callback);
/* ... and wait until all of them have reported back that
they're no longer running. */
- iterate_over_lwps (ptid, stop_wait_callback, NULL);
+ iterate_over_lwps (ptid, stop_wait_callback);
/* Kill all LWP's ... */
- iterate_over_lwps (ptid, kill_callback, NULL);
+ iterate_over_lwps (ptid, kill_callback);
/* ... and wait until we've flushed all events. */
- iterate_over_lwps (ptid, kill_wait_callback, NULL);
+ iterate_over_lwps (ptid, kill_wait_callback);
}
target_mourn_inferior (inferior_ptid);
const gdb_byte *writebuf, ULONGEST offset, ULONGEST len,
ULONGEST *xfered_len);
-static enum target_xfer_status
-linux_proc_xfer_spu (enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len, ULONGEST *xfered_len);
-
static enum target_xfer_status
linux_proc_xfer_partial (enum target_object object,
const char *annex, gdb_byte *readbuf,
return linux_nat_xfer_osdata (object, annex, readbuf, writebuf,
offset, len, xfered_len);
- if (object == TARGET_OBJECT_SPU)
- return linux_proc_xfer_spu (object, annex, readbuf, writebuf,
- offset, len, xfered_len);
-
/* GDB calculates all addresses in the largest possible address
width.
The address width must be masked before its final use - either by
}
}
-const char *
+std::string
linux_nat_target::pid_to_str (ptid_t ptid)
{
- static char buf[64];
-
if (ptid.lwp_p ()
&& (ptid.pid () != ptid.lwp ()
|| num_lwps (ptid.pid ()) > 1))
- {
- snprintf (buf, sizeof (buf), "LWP %ld", ptid.lwp ());
- return buf;
- }
+ return string_printf ("LWP %ld", ptid.lwp ());
return normal_pid_to_str (ptid);
}
}
-/* Enumerate spufs IDs for process PID. */
-static LONGEST
-spu_enumerate_spu_ids (int pid, gdb_byte *buf, ULONGEST offset, ULONGEST len)
-{
- enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
- LONGEST pos = 0;
- LONGEST written = 0;
- char path[128];
- DIR *dir;
- struct dirent *entry;
-
- xsnprintf (path, sizeof path, "/proc/%d/fd", pid);
- dir = opendir (path);
- if (!dir)
- return -1;
-
- rewinddir (dir);
- while ((entry = readdir (dir)) != NULL)
- {
- struct stat st;
- struct statfs stfs;
- int fd;
-
- fd = atoi (entry->d_name);
- if (!fd)
- continue;
-
- xsnprintf (path, sizeof path, "/proc/%d/fd/%d", pid, fd);
- if (stat (path, &st) != 0)
- continue;
- if (!S_ISDIR (st.st_mode))
- continue;
-
- if (statfs (path, &stfs) != 0)
- continue;
- if (stfs.f_type != SPUFS_MAGIC)
- continue;
-
- if (pos >= offset && pos + 4 <= offset + len)
- {
- store_unsigned_integer (buf + pos - offset, 4, byte_order, fd);
- written += 4;
- }
- pos += 4;
- }
-
- closedir (dir);
- return written;
-}
-
-/* Implement the to_xfer_partial interface for the TARGET_OBJECT_SPU
- object type, using the /proc file system. */
-
-static enum target_xfer_status
-linux_proc_xfer_spu (enum target_object object,
- const char *annex, gdb_byte *readbuf,
- const gdb_byte *writebuf,
- ULONGEST offset, ULONGEST len, ULONGEST *xfered_len)
-{
- char buf[128];
- int fd = 0;
- int ret = -1;
- int pid = inferior_ptid.lwp ();
-
- if (!annex)
- {
- if (!readbuf)
- return TARGET_XFER_E_IO;
- else
- {
- LONGEST l = spu_enumerate_spu_ids (pid, readbuf, offset, len);
-
- if (l < 0)
- return TARGET_XFER_E_IO;
- else if (l == 0)
- return TARGET_XFER_EOF;
- else
- {
- *xfered_len = (ULONGEST) l;
- return TARGET_XFER_OK;
- }
- }
- }
-
- xsnprintf (buf, sizeof buf, "/proc/%d/fd/%s", pid, annex);
- fd = gdb_open_cloexec (buf, writebuf? O_WRONLY : O_RDONLY, 0);
- if (fd <= 0)
- return TARGET_XFER_E_IO;
-
- if (offset != 0
- && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
- {
- close (fd);
- return TARGET_XFER_EOF;
- }
-
- if (writebuf)
- ret = write (fd, writebuf, (size_t) len);
- else if (readbuf)
- ret = read (fd, readbuf, (size_t) len);
-
- close (fd);
-
- if (ret < 0)
- return TARGET_XFER_E_IO;
- else if (ret == 0)
- return TARGET_XFER_EOF;
- else
- {
- *xfered_len = (ULONGEST) ret;
- return TARGET_XFER_OK;
- }
-}
-
-
/* Parse LINE as a signal set and add its set bits to SIGS. */
static void
return TARGET_XFER_OK;
}
-static void
-cleanup_target_stop (void *arg)
-{
- ptid_t *ptid = (ptid_t *) arg;
-
- gdb_assert (arg != NULL);
-
- /* Unpause all */
- target_continue_no_signal (*ptid);
-}
-
std::vector<static_tracepoint_marker>
linux_nat_target::static_tracepoint_markers_by_strid (const char *strid)
{
char s[IPA_CMD_BUF_SIZE];
- struct cleanup *old_chain;
int pid = inferior_ptid.pid ();
std::vector<static_tracepoint_marker> markers;
const char *p = s;
agent_run_command (pid, s, strlen (s) + 1);
- old_chain = make_cleanup (cleanup_target_stop, &ptid);
+ /* Unpause all. */
+ SCOPE_EXIT { target_continue_no_signal (ptid); };
while (*p++ == 'm')
{
p = s;
}
- do_cleanups (old_chain);
-
return markers;
}
bool
linux_nat_target::supports_non_stop ()
{
- return 1;
+ return true;
}
/* to_always_non_stop_p implementation. */
bool
linux_nat_target::always_non_stop_p ()
{
- return 1;
+ return true;
}
-/* True if we want to support multi-process. To be removed when GDB
- supports multi-exec. */
-
-int linux_multi_process = 1;
-
bool
linux_nat_target::supports_multi_process ()
{
- return linux_multi_process;
+ return true;
}
bool
linux_nat_target::supports_disable_randomization ()
{
#ifdef HAVE_PERSONALITY
- return 1;
+ return true;
#else
- return 0;
+ return false;
#endif
}
int old_errno = errno;
if (debug_linux_nat)
- ui_file_write_async_safe (gdb_stdlog,
- "sigchld\n", sizeof ("sigchld\n") - 1);
+ gdb_stdlog->write_async_safe ("sigchld\n", sizeof ("sigchld\n") - 1);
if (signo == SIGCHLD
&& linux_nat_event_pipe[0] != -1)
static void
handle_target_event (int error, gdb_client_data client_data)
{
- inferior_event_handler (INF_REG_EVENT, NULL);
+ inferior_event_handler (INF_REG_EVENT);
}
/* Create/destroy the target events pipe. Returns previous state. */
return previous;
}
+int
+linux_nat_target::async_wait_fd ()
+{
+ return linux_nat_event_pipe[0];
+}
+
/* target_async implementation. */
void
event came out. */
static int
-linux_nat_stop_lwp (struct lwp_info *lwp, void *data)
+linux_nat_stop_lwp (struct lwp_info *lwp)
{
if (!lwp->stopped)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "LNSL: running -> suspending %s\n",
- target_pid_to_str (lwp->ptid));
+ linux_nat_debug_printf ("running -> suspending %s",
+ target_pid_to_str (lwp->ptid).c_str ());
if (lwp->last_resume_kind == resume_stop)
{
- if (debug_linux_nat)
- fprintf_unfiltered (gdb_stdlog,
- "linux-nat: already stopping LWP %ld at "
- "GDB's request\n",
- lwp->ptid.lwp ());
+ linux_nat_debug_printf ("already stopping LWP %ld at GDB's request",
+ lwp->ptid.lwp ());
return 0;
}
- stop_callback (lwp, NULL);
+ stop_callback (lwp);
lwp->last_resume_kind = resume_stop;
}
else
if (debug_linux_nat)
{
- if (find_thread_ptid (lwp->ptid)->stop_requested)
- fprintf_unfiltered (gdb_stdlog,
- "LNSL: already stopped/stop_requested %s\n",
- target_pid_to_str (lwp->ptid));
+ if (find_thread_ptid (linux_target, lwp->ptid)->stop_requested)
+ linux_nat_debug_printf ("already stopped/stop_requested %s",
+ target_pid_to_str (lwp->ptid).c_str ());
else
- fprintf_unfiltered (gdb_stdlog,
- "LNSL: already stopped/no "
- "stop_requested yet %s\n",
- target_pid_to_str (lwp->ptid));
+ linux_nat_debug_printf ("already stopped/no stop_requested yet %s",
+ target_pid_to_str (lwp->ptid).c_str ());
}
}
return 0;
void
linux_nat_target::stop (ptid_t ptid)
{
- iterate_over_lwps (ptid, linux_nat_stop_lwp, NULL);
+ iterate_over_lwps (ptid, linux_nat_stop_lwp);
}
void
pid = ptid.pid ();
}
- inf = find_inferior_pid (pid);
+ inf = find_inferior_pid (this, pid);
gdb_assert (inf != NULL);
return inf->aspace;
}
return inferior_ptid;
}
+void _initialize_linux_nat ();
void
-_initialize_linux_nat (void)
+_initialize_linux_nat ()
{
add_setshow_zuinteger_cmd ("lin-lwp", class_maintenance,
&debug_linux_nat, _("\
NULL,
&setdebuglist, &showdebuglist);
- /* Save this mask as the default. */
- sigprocmask (SIG_SETMASK, NULL, &normal_mask);
-
/* Install a SIGCHLD handler. */
sigchld_action.sa_handler = sigchld_handler;
sigemptyset (&sigchld_action.sa_mask);
sigaction (SIGCHLD, &sigchld_action, NULL);
/* Make sure we don't block SIGCHLD during a sigsuspend. */
- sigprocmask (SIG_SETMASK, NULL, &suspend_mask);
+ gdb_sigmask (SIG_SETMASK, NULL, &suspend_mask);
sigdelset (&suspend_mask, SIGCHLD);
sigemptyset (&blocked_mask);