#include "inferior.h"
#include "target.h"
#include "regcache.h"
+#include "gdbcmd.h"
-#define DEBUG 1
-
-#if DEBUG
+static int debug_lin_lwp;
extern const char *strsignal (int sig);
-#endif
/* On Linux there are no real LWP's. The closest thing to LWP's are
processes sharing the same VM space. A multi-threaded process is
cannot use it since GDB must work on older systems too.
- When a traced, cloned process exits and is waited for by the
- debugger, the kernel reassigns it to the origional parent and
+ debugger, the kernel reassigns it to the original parent and
keeps it around as a "zombie". Somehow, the LinuxThreads library
doesn't notice this, which leads to the "zombie problem": When
debugged a multi-threaded process that spawns a lot of threads
{
/* The process id of the LWP. This is a combination of the LWP id
and overall process id. */
- int pid;
+ ptid_t ptid;
/* Non-zero if we sent this LWP a SIGSTOP (but the LWP didn't report
it back yet). */
static int threaded;
\f
-#ifndef TIDGET
-#define TIDGET(PID) (((PID) & 0x7fffffff) >> 16)
-#define PIDGET(PID) (((PID) & 0xffff))
-#define MERGEPID(PID, TID) (((PID) & 0xffff) | ((TID) << 16))
-#endif
-
-#define THREAD_FLAG 0x80000000
-#define is_lwp(pid) (((pid) & THREAD_FLAG) == 0 && TIDGET (pid))
-#define GET_LWP(pid) TIDGET (pid)
-#define GET_PID(pid) PIDGET (pid)
-#define BUILD_LWP(tid, pid) MERGEPID (pid, tid)
+#define GET_LWP(ptid) ptid_get_lwp (ptid)
+#define GET_PID(ptid) ptid_get_pid (ptid)
+#define is_lwp(ptid) (GET_LWP (ptid) != 0)
+#define BUILD_LWP(lwp, pid) ptid_build (pid, lwp, 0)
#define is_cloned(pid) (GET_LWP (pid) != GET_PID (pid))
/* If the last reported event was a SIGTRAP, this variable is set to
the process id of the LWP/thread that got it. */
-int trap_pid;
+ptid_t trap_ptid;
\f
/* This module's target-specific operations. */
/* Since we cannot wait (in lin_lwp_wait) for the initial process and
any cloned processes with a single call to waitpid, we have to use
- use the WNOHANG flag and call waitpid in a loop. To optimize
+ the WNOHANG flag and call waitpid in a loop. To optimize
things a bit we use `sigsuspend' to wake us up when a process has
something to report (it will send us a SIGCHLD if it has). To make
this work we have to juggle with the signal mask. We save the
- origional signal mask such that we can restore it before creating a
+ original signal mask such that we can restore it before creating a
new process in order to avoid blocking certain signals in the
inferior. We then block SIGCHLD during the waitpid/sigsuspend
loop. */
-/* Origional signal mask. */
+/* Original signal mask. */
static sigset_t normal_mask;
/* Signal mask for use with sigsuspend in lin_lwp_wait, initialized in
\f
/* Prototypes for local functions. */
-static void lin_lwp_mourn_inferior (void);
+static int stop_wait_callback (struct lwp_info *lp, void *data);
\f
-/* Initialize the list of LWPs. */
+/* Initialize the list of LWPs. Note that this module, contrary to
+ what GDB's generic threads layer does for its thread list,
+ re-initializes the LWP lists whenever we mourn or detach (which
+ doesn't involve mourning) the inferior. */
static void
init_lwp_list (void)
Return a pointer to the structure describing the new LWP. */
static struct lwp_info *
-add_lwp (int pid)
+add_lwp (ptid_t ptid)
{
struct lwp_info *lp;
- gdb_assert (is_lwp (pid));
+ gdb_assert (is_lwp (ptid));
lp = (struct lwp_info *) xmalloc (sizeof (struct lwp_info));
memset (lp, 0, sizeof (struct lwp_info));
- lp->pid = pid;
+ lp->ptid = ptid;
lp->next = lwp_list;
lwp_list = lp;
/* Remove the LWP specified by PID from the list. */
static void
-delete_lwp (int pid)
+delete_lwp (ptid_t ptid)
{
struct lwp_info *lp, *lpprev;
lpprev = NULL;
for (lp = lwp_list; lp; lpprev = lp, lp = lp->next)
- if (lp->pid == pid)
+ if (ptid_equal (lp->ptid, ptid))
break;
if (!lp)
to PID. If no corresponding LWP could be found, return NULL. */
static struct lwp_info *
-find_lwp_pid (int pid)
+find_lwp_pid (ptid_t ptid)
{
struct lwp_info *lp;
+ int lwp;
- if (is_lwp (pid))
- pid = GET_LWP (pid);
+ if (is_lwp (ptid))
+ lwp = GET_LWP (ptid);
+ else
+ lwp = GET_PID (ptid);
for (lp = lwp_list; lp; lp = lp->next)
- if (pid == GET_LWP (lp->pid))
+ if (lwp == GET_LWP (lp->ptid))
return lp;
return NULL;
}
\f
-/* Helper functions. */
-
-static void
-restore_inferior_pid (void *arg)
-{
- int *saved_pid_ptr = arg;
- inferior_pid = *saved_pid_ptr;
- xfree (arg);
-}
-
-static struct cleanup *
-save_inferior_pid (void)
-{
- int *saved_pid_ptr;
-
- saved_pid_ptr = xmalloc (sizeof (int));
- *saved_pid_ptr = inferior_pid;
- return make_cleanup (restore_inferior_pid, saved_pid_ptr);
-}
-\f
-
/* Implementation of the PREPARE_TO_PROCEED hook for the Linux LWP
layer.
int
lin_lwp_prepare_to_proceed (void)
{
- if (trap_pid && inferior_pid != trap_pid)
+ if (! ptid_equal (trap_ptid, null_ptid)
+ && ! ptid_equal (inferior_ptid, trap_ptid))
{
/* Switched over from TRAP_PID. */
CORE_ADDR stop_pc = read_pc ();
/* Avoid switching where it wouldn't do any good, i.e. if both
threads are at the same breakpoint. */
- trap_pc = read_pc_pid (trap_pid);
+ trap_pc = read_pc_pid (trap_ptid);
if (trap_pc != stop_pc && breakpoint_here_p (trap_pc))
{
/* User hasn't deleted the breakpoint. Return non-zero, and
switch back to TRAP_PID. */
- inferior_pid = trap_pid;
+ inferior_ptid = trap_ptid;
/* FIXME: Is this stuff really necessary? */
flush_cached_frames ();
process. */
void
-lin_lwp_attach_lwp (int pid, int verbose)
+lin_lwp_attach_lwp (ptid_t ptid, int verbose)
{
struct lwp_info *lp;
- gdb_assert (is_lwp (pid));
+ gdb_assert (is_lwp (ptid));
if (verbose)
- printf_filtered ("[New %s]\n", target_pid_to_str (pid));
+ printf_filtered ("[New %s]\n", target_pid_to_str (ptid));
- if (ptrace (PTRACE_ATTACH, GET_LWP (pid), 0, 0) < 0)
- error ("Can't attach %s: %s", target_pid_to_str (pid), strerror (errno));
+ /* We assume that we're already tracing the initial process. */
+ if (is_cloned (ptid) && ptrace (PTRACE_ATTACH, GET_LWP (ptid), 0, 0) < 0)
+ error ("Can't attach %s: %s", target_pid_to_str (ptid), strerror (errno));
- lp = add_lwp (pid);
- lp->signalled = 1;
+ lp = find_lwp_pid (ptid);
+ if (lp == NULL)
+ lp = add_lwp (ptid);
+
+ if (is_cloned (ptid))
+ lp->signalled = 1;
}
static void
lin_lwp_attach (char *args, int from_tty)
{
+ struct lwp_info *lp;
+
/* FIXME: We should probably accept a list of process id's, and
attach all of them. */
- error("Not implemented yet");
+ child_ops.to_attach (args, from_tty);
+
+ /* Add the initial process as the first LWP to the list. */
+ lp = add_lwp (BUILD_LWP (PIDGET (inferior_ptid), PIDGET (inferior_ptid)));
+
+ /* Make sure the initial process is stopped. The user-level threads
+ layer might want to poke around in the inferior, and that won't
+ work if things haven't stabilized yet. */
+ lp->signalled = 1;
+ stop_wait_callback (lp, NULL);
+ gdb_assert (lp->status == 0);
+
+ /* Fake the SIGSTOP that core GDB expects. */
+ lp->status = W_STOPCODE (SIGSTOP);
+}
+
+static int
+detach_callback (struct lwp_info *lp, void *data)
+{
+ gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status));
+
+ if (debug_lin_lwp && lp->status)
+ fprintf_unfiltered (gdb_stdlog, "Pending %s for LWP %ld on detach.\n",
+ strsignal (WSTOPSIG (lp->status)), GET_LWP (lp->ptid));
+
+ while (lp->signalled && lp->stopped)
+ {
+ if (ptrace (PTRACE_CONT, GET_LWP (lp->ptid), 0,
+ WSTOPSIG (lp->status)) < 0)
+ error ("Can't continue %s: %s", target_pid_to_str (lp->ptid),
+ strerror (errno));
+
+ lp->stopped = 0;
+ lp->status = 0;
+ stop_wait_callback (lp, NULL);
+
+ gdb_assert (lp->status == 0 || WIFSTOPPED (lp->status));
+ }
+
+ if (is_cloned (lp->ptid))
+ {
+ if (ptrace (PTRACE_DETACH, GET_LWP (lp->ptid), 0,
+ WSTOPSIG (lp->status)) < 0)
+ error ("Can't detach %s: %s", target_pid_to_str (lp->ptid),
+ strerror (errno));
+
+ delete_lwp (lp->ptid);
+ }
+
+ return 0;
}
static void
lin_lwp_detach (char *args, int from_tty)
{
- /* FIXME: Provide implementation when we implement lin_lwp_attach. */
- error ("Not implemented yet");
+ iterate_over_lwps (detach_callback, NULL);
+
+ /* Only the initial (uncloned) process should be left right now. */
+ gdb_assert (num_lwps == 1);
+
+ trap_ptid = null_ptid;
+
+ /* Destroy LWP info; it's no longer valid. */
+ init_lwp_list ();
+
+ /* Restore the original signal mask. */
+ sigprocmask (SIG_SETMASK, &normal_mask, NULL);
+ sigemptyset (&blocked_mask);
+
+ inferior_ptid = pid_to_ptid (GET_PID (inferior_ptid));
+ child_ops.to_detach (args, from_tty);
}
\f
{
struct lwp_info *lp = data;
- if (tp->private->lwpid == GET_LWP (lp->pid))
+ if (tp->private->lwpid == GET_LWP (lp->ptid))
return 1;
return 0;
/* FIXME: kettenis/2000-08-26: This should really be handled
properly by core GDB. */
- tp = find_thread_pid (lp->pid);
+ tp = find_thread_pid (lp->ptid);
if (tp == NULL)
tp = iterate_over_threads (find_lwp_callback, lp);
gdb_assert (tp);
}
#endif
- child_resume (GET_LWP (lp->pid), 0, TARGET_SIGNAL_0);
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), 0, TARGET_SIGNAL_0);
lp->stopped = 0;
lp->step = 0;
}
}
static void
-lin_lwp_resume (int pid, int step, enum target_signal signo)
+lin_lwp_resume (ptid_t ptid, int step, enum target_signal signo)
{
struct lwp_info *lp;
int resume_all;
STEP is non-zero, a specific PID means `step only this process
id'. But if STEP is zero, then PID means `continue *all*
processes, but give the signal only to this one'. */
- resume_all = (pid == -1) || !step;
+ resume_all = (PIDGET (ptid) == -1) || !step;
/* If PID is -1, it's the current inferior that should be
handled special. */
- if (pid == -1)
- pid = inferior_pid;
+ if (PIDGET (ptid) == -1)
+ ptid = inferior_ptid;
- lp = find_lwp_pid (pid);
+ lp = find_lwp_pid (ptid);
if (lp)
{
- pid = GET_LWP (lp->pid);
+ ptid = pid_to_ptid (GET_LWP (lp->ptid));
/* Remember if we're stepping. */
lp->step = step;
if (resume_all)
iterate_over_lwps (resume_callback, NULL);
- child_resume (pid, step, signo);
+ child_resume (ptid, step, signo);
}
\f
{
int ret;
- ret = kill (GET_LWP (lp->pid), SIGSTOP);
+ ret = kill (GET_LWP (lp->ptid), SIGSTOP);
gdb_assert (ret == 0);
lp->signalled = 1;
gdb_assert (lp->status == 0);
- pid = waitpid (GET_LWP (lp->pid), &status,
- is_cloned (lp->pid) ? __WCLONE : 0);
+ pid = waitpid (GET_LWP (lp->ptid), &status,
+ is_cloned (lp->ptid) ? __WCLONE : 0);
if (pid == -1 && errno == ECHILD)
/* OK, the proccess has disappeared. We'll catch the actual
exit event in lin_lwp_wait. */
return 0;
- gdb_assert (pid == GET_LWP (lp->pid));
+ gdb_assert (pid == GET_LWP (lp->ptid));
if (WIFEXITED (status) || WIFSIGNALED (status))
{
gdb_assert (num_lwps > 1);
- if (in_thread_list (lp->pid))
+ if (in_thread_list (lp->ptid))
{
/* Core GDB cannot deal with us deleting the current
thread. */
- if (lp->pid != inferior_pid)
- delete_thread (lp->pid);
+ if (!ptid_equal (lp->ptid, inferior_ptid))
+ delete_thread (lp->ptid);
printf_unfiltered ("[%s exited]\n",
- target_pid_to_str (lp->pid));
+ target_pid_to_str (lp->ptid));
}
-#if DEBUG
- printf ("%s exited.\n", target_pid_to_str (lp->pid));
-#endif
- delete_lwp (lp->pid);
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "%s exited.\n", target_pid_to_str (lp->ptid));
+
+ delete_lwp (lp->ptid);
return 0;
}
if (WSTOPSIG (status) != SIGSTOP)
{
if (WSTOPSIG (status) == SIGTRAP
- && breakpoint_inserted_here_p (read_pc_pid (pid)
+ && breakpoint_inserted_here_p (read_pc_pid (pid_to_ptid (pid))
- DECR_PC_AFTER_BREAK))
{
/* If a LWP other than the LWP that we're reporting an
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. */
-#if DEBUG
- printf ("Tripped breakpoint at %lx in LWP %d"
- " while waiting for SIGSTOP.\n",
- (long) read_pc_pid (lp->pid), pid);
-#endif
+
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Tripped breakpoint at %lx in LWP %d"
+ " while waiting for SIGSTOP.\n",
+ (long) read_pc_pid (lp->ptid), pid);
+
/* Set the PC to before the trap. */
if (DECR_PC_AFTER_BREAK)
- write_pc_pid (read_pc_pid (pid) - DECR_PC_AFTER_BREAK, pid);
+ write_pc_pid (read_pc_pid (pid_to_ptid (pid))
+ - DECR_PC_AFTER_BREAK,
+ pid_to_ptid (pid));
}
else
{
-#if DEBUG
- printf ("Received %s in LWP %d while waiting for SIGSTOP.\n",
- strsignal (WSTOPSIG (status)), pid);
-#endif
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Received %s in LWP %d while waiting for SIGSTOP.\n",
+ strsignal (WSTOPSIG (status)), pid);
+
/* The thread was stopped with a signal other than
SIGSTOP, and didn't accidentiliy trip a breakpoint.
Record the wait status. */
return (lp->stopped == 0);
}
-static int
-lin_lwp_wait (int pid, struct target_waitstatus *ourstatus)
+static ptid_t
+lin_lwp_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
{
struct lwp_info *lp = NULL;
int options = 0;
int status = 0;
+ pid_t pid = PIDGET (ptid);
/* Make sure SIGCHLD is blocked. */
if (! sigismember (&blocked_mask, SIGCHLD))
lp = iterate_over_lwps (status_callback, NULL);
if (lp)
{
-#if DEBUG
- printf ("Using pending wait status for LWP %d.\n",
- GET_LWP (lp->pid));
-#endif
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Using pending wait status for LWP %ld.\n",
+ GET_LWP (lp->ptid));
+
status = lp->status;
lp->status = 0;
}
processes. */
options = __WCLONE | WNOHANG;
}
- else if (is_lwp (pid))
+ else if (is_lwp (ptid))
{
-#if DEBUG
- printf ("Waiting for specific LWP %d.\n", GET_LWP (pid));
-#endif
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Waiting for specific LWP %ld.\n",
+ GET_LWP (ptid));
+
/* We have a specific LWP to check. */
- lp = find_lwp_pid (GET_LWP (pid));
+ lp = find_lwp_pid (ptid);
gdb_assert (lp);
status = lp->status;
lp->status = 0;
-#if DEBUG
- if (status)
- printf ("Using pending wait status for LWP %d.\n",
- GET_LWP (lp->pid));
-#endif
+
+ if (debug_lin_lwp)
+ if (status)
+ fprintf_unfiltered (gdb_stdlog,
+ "Using pending wait status for LWP %ld.\n",
+ GET_LWP (lp->ptid));
/* If we have to wait, take into account whether PID is a cloned
process or not. And we have to convert it to something that
the layer beneath us can understand. */
- options = is_cloned (lp->pid) ? __WCLONE : 0;
- pid = GET_LWP (pid);
+ options = is_cloned (lp->ptid) ? __WCLONE : 0;
+ pid = GET_LWP (ptid);
}
if (status && lp->signalled)
/* Resume the thread. It should halt immediately returning the
pending SIGSTOP. */
- child_resume (GET_LWP (lp->pid), lp->step, TARGET_SIGNAL_0);
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
+ TARGET_SIGNAL_0);
lp->stopped = 0;
/* This should catch the pending SIGSTOP. */
{
gdb_assert (pid == -1 || lwpid == pid);
- lp = find_lwp_pid (lwpid);
+ lp = find_lwp_pid (pid_to_ptid (lwpid));
if (! lp)
{
- lp = add_lwp (BUILD_LWP (lwpid, inferior_pid));
+ lp = add_lwp (BUILD_LWP (lwpid, GET_PID (inferior_ptid)));
if (threaded)
{
gdb_assert (WIFSTOPPED (status)
&& WSTOPSIG (status) == SIGSTOP);
lp->signalled = 1;
- if (! in_thread_list (inferior_pid))
+ if (! in_thread_list (inferior_ptid))
{
- inferior_pid = BUILD_LWP (inferior_pid, inferior_pid);
- add_thread (inferior_pid);
+ inferior_ptid = BUILD_LWP (GET_PID (inferior_ptid),
+ GET_PID (inferior_ptid));
+ add_thread (inferior_ptid);
}
- add_thread (lp->pid);
+ add_thread (lp->ptid);
printf_unfiltered ("[New %s]\n",
- target_pid_to_str (lp->pid));
+ target_pid_to_str (lp->ptid));
}
}
left in the process. */
if ((WIFEXITED (status) || WIFSIGNALED (status)) && num_lwps > 1)
{
- if (in_thread_list (lp->pid))
+ if (in_thread_list (lp->ptid))
{
/* Core GDB cannot deal with us deleting the current
thread. */
- if (lp->pid != inferior_pid)
- delete_thread (lp->pid);
+ if (! ptid_equal (lp->ptid, inferior_ptid))
+ delete_thread (lp->ptid);
printf_unfiltered ("[%s exited]\n",
- target_pid_to_str (lp->pid));
+ target_pid_to_str (lp->ptid));
}
-#if DEBUG
- printf ("%s exited.\n", target_pid_to_str (lp->pid));
-#endif
- delete_lwp (lp->pid);
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "%s exited.\n",
+ target_pid_to_str (lp->ptid));
+
+ delete_lwp (lp->ptid);
/* Make sure there is at least one thread running. */
gdb_assert (iterate_over_lwps (running_callback, NULL));
if (lp->signalled && WIFSTOPPED (status)
&& WSTOPSIG (status) == SIGSTOP)
{
-#if DEBUG
- printf ("Delayed SIGSTOP caught for %s.\n",
- target_pid_to_str (lp->pid));
-#endif
+ if (debug_lin_lwp)
+ fprintf_unfiltered (gdb_stdlog,
+ "Delayed SIGSTOP caught for %s.\n",
+ target_pid_to_str (lp->ptid));
+
/* This is a delayed SIGSTOP. */
lp->signalled = 0;
- child_resume (GET_LWP (lp->pid), lp->step, TARGET_SIGNAL_0);
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step,
+ TARGET_SIGNAL_0);
lp->stopped = 0;
/* Discard the event. */
&& signal_print_state (signo) == 0
&& signal_pass_state (signo) == 1)
{
- child_resume (GET_LWP (lp->pid), lp->step, signo);
+ child_resume (pid_to_ptid (GET_LWP (lp->ptid)), lp->step, signo);
lp->stopped = 0;
status = 0;
goto retry;
process id. */
if (WIFSTOPPED (status) && WSTOPSIG (status) == SIGTRAP)
- trap_pid = (threaded ? lp->pid : GET_LWP (lp->pid));
+ trap_ptid = (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid)));
else
- trap_pid = 0;
+ trap_ptid = null_ptid;
store_waitstatus (ourstatus, status);
- return (threaded ? lp->pid : GET_LWP (lp->pid));
+ return (threaded ? lp->ptid : pid_to_ptid (GET_LWP (lp->ptid)));
}
static int
kill_callback (struct lwp_info *lp, void *data)
{
- ptrace (PTRACE_KILL, GET_LWP (lp->pid), 0, 0);
+ ptrace (PTRACE_KILL, GET_LWP (lp->ptid), 0, 0);
return 0;
}
/* For cloned processes we must check both with __WCLONE and
without, since the exit status of a cloned process isn't reported
with __WCLONE. */
- if (is_cloned (lp->pid))
+ if (is_cloned (lp->ptid))
{
do
{
- pid = waitpid (GET_LWP (lp->pid), NULL, __WCLONE);
+ pid = waitpid (GET_LWP (lp->ptid), NULL, __WCLONE);
}
- while (pid == GET_LWP (lp->pid));
+ while (pid == GET_LWP (lp->ptid));
gdb_assert (pid == -1 && errno == ECHILD);
}
do
{
- pid = waitpid (GET_LWP (lp->pid), NULL, 0);
+ pid = waitpid (GET_LWP (lp->ptid), NULL, 0);
}
- while (pid == GET_LWP (lp->pid));
+ while (pid == GET_LWP (lp->ptid));
gdb_assert (pid == -1 && errno == ECHILD);
return 0;
static void
lin_lwp_create_inferior (char *exec_file, char *allargs, char **env)
{
- struct target_ops *target_beneath;
-
- init_lwp_list ();
-
-#if 0
- target_beneath = find_target_beneath (&lin_lwp_ops);
-#else
- target_beneath = &child_ops;
-#endif
- target_beneath->to_create_inferior (exec_file, allargs, env);
+ child_ops.to_create_inferior (exec_file, allargs, env);
}
static void
lin_lwp_mourn_inferior (void)
{
- struct target_ops *target_beneath;
+ trap_ptid = null_ptid;
+ /* Destroy LWP info; it's no longer valid. */
init_lwp_list ();
- trap_pid = 0;
-
- /* Restore the origional signal mask. */
+ /* Restore the original signal mask. */
sigprocmask (SIG_SETMASK, &normal_mask, NULL);
sigemptyset (&blocked_mask);
-#if 0
- target_beneath = find_target_beneath (&lin_lwp_ops);
-#else
- target_beneath = &child_ops;
-#endif
- target_beneath->to_mourn_inferior ();
+ child_ops.to_mourn_inferior ();
}
static void
lin_lwp_fetch_registers (int regno)
{
- struct cleanup *old_chain = save_inferior_pid ();
+ struct cleanup *old_chain = save_inferior_ptid ();
- if (is_lwp (inferior_pid))
- inferior_pid = GET_LWP (inferior_pid);
+ if (is_lwp (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
fetch_inferior_registers (regno);
static void
lin_lwp_store_registers (int regno)
{
- struct cleanup *old_chain = save_inferior_pid ();
+ struct cleanup *old_chain = save_inferior_ptid ();
- if (is_lwp (inferior_pid))
- inferior_pid = GET_LWP (inferior_pid);
+ if (is_lwp (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
store_inferior_registers (regno);
struct mem_attrib *attrib,
struct target_ops *target)
{
- struct cleanup *old_chain = save_inferior_pid ();
+ struct cleanup *old_chain = save_inferior_ptid ();
int xfer;
- if (is_lwp (inferior_pid))
- inferior_pid = GET_LWP (inferior_pid);
+ if (is_lwp (inferior_ptid))
+ inferior_ptid = pid_to_ptid (GET_LWP (inferior_ptid));
xfer = child_xfer_memory (memaddr, myaddr, len, write, attrib, target);
}
static int
-lin_lwp_thread_alive (int pid)
+lin_lwp_thread_alive (ptid_t ptid)
{
- gdb_assert (is_lwp (pid));
+ gdb_assert (is_lwp (ptid));
errno = 0;
- ptrace (PTRACE_PEEKUSER, GET_LWP (pid), 0, 0);
+ ptrace (PTRACE_PEEKUSER, GET_LWP (ptid), 0, 0);
if (errno)
return 0;
}
static char *
-lin_lwp_pid_to_str (int pid)
+lin_lwp_pid_to_str (ptid_t ptid)
{
static char buf[64];
- if (is_lwp (pid))
+ if (is_lwp (ptid))
{
- snprintf (buf, sizeof (buf), "LWP %d", GET_LWP (pid));
+ snprintf (buf, sizeof (buf), "LWP %ld", GET_LWP (ptid));
return buf;
}
- return normal_pid_to_str (pid);
+ return normal_pid_to_str (ptid);
}
static void
add_target (&lin_lwp_ops);
thread_db_init (&lin_lwp_ops);
- /* Save the origional signal mask. */
+ /* Save the original signal mask. */
sigprocmask (SIG_SETMASK, NULL, &normal_mask);
action.sa_handler = sigchld_handler;
sigdelset (&suspend_mask, SIGCHLD);
sigemptyset (&blocked_mask);
+
+ add_show_from_set (add_set_cmd ("lin-lwp", no_class, var_zinteger,
+ (char *) &debug_lin_lwp,
+ "Set debugging of linux lwp module.\n\
+Enables printf debugging output.\n",
+ &setdebuglist),
+ &showdebuglist);
}
\f