blob: a476031faf48be31b9dc5911771caf525d23cbbc [file] [log] [blame]
/* Low level interface to ptrace, for the remote server for GDB.
Copyright (C) 1995-1996, 1998-2012 Free Software Foundation, Inc.
This file is part of GDB.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "server.h"
#include "linux-low.h"
#include "linux-osdata.h"
#include "agent.h"
#include <sys/wait.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/ptrace.h>
#include "linux-ptrace.h"
#include "linux-procfs.h"
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/syscall.h>
#include <sched.h>
#include <ctype.h>
#include <pwd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <sys/uio.h>
#ifndef ELFMAG0
/* Don't include <linux/elf.h> here. If it got included by gdb_proc_service.h
then ELFMAG0 will have been defined. If it didn't get included by
gdb_proc_service.h then including it will likely introduce a duplicate
definition of elf_fpregset_t. */
#include <elf.h>
#endif
#ifndef SPUFS_MAGIC
#define SPUFS_MAGIC 0x23c9b64e
#endif
#ifdef HAVE_PERSONALITY
# include <sys/personality.h>
# if !HAVE_DECL_ADDR_NO_RANDOMIZE
# define ADDR_NO_RANDOMIZE 0x0040000
# endif
#endif
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#ifndef W_STOPCODE
#define W_STOPCODE(sig) ((sig) << 8 | 0x7f)
#endif
/* This is the kernel's hard limit. Not to be confused with
SIGRTMIN. */
#ifndef __SIGRTMIN
#define __SIGRTMIN 32
#endif
#ifdef __UCLIBC__
#if !(defined(__UCLIBC_HAS_MMU__) || defined(__ARCH_HAS_MMU__))
/* PTRACE_TEXT_ADDR and friends. */
#include <asm/ptrace.h>
#define HAS_NOMMU
#endif
#endif
#ifndef HAVE_ELF32_AUXV_T
/* Copied from glibc's elf.h. */
typedef struct
{
uint32_t a_type; /* Entry type */
union
{
uint32_t a_val; /* Integer value */
/* We use to have pointer elements added here. We cannot do that,
though, since it does not work when using 32-bit definitions
on 64-bit platforms and vice versa. */
} a_un;
} Elf32_auxv_t;
#endif
#ifndef HAVE_ELF64_AUXV_T
/* Copied from glibc's elf.h. */
typedef struct
{
uint64_t a_type; /* Entry type */
union
{
uint64_t a_val; /* Integer value */
/* We use to have pointer elements added here. We cannot do that,
though, since it does not work when using 32-bit definitions
on 64-bit platforms and vice versa. */
} a_un;
} Elf64_auxv_t;
#endif
/* ``all_threads'' is keyed by the LWP ID, which we use as the GDB protocol
representation of the thread ID.
``all_lwps'' is keyed by the process ID - which on Linux is (presently)
the same as the LWP ID.
``all_processes'' is keyed by the "overall process ID", which
GNU/Linux calls tgid, "thread group ID". */
struct inferior_list all_lwps;
/* A list of all unknown processes which receive stop signals. Some
other process will presumably claim each of these as forked
children momentarily. */
struct simple_pid_list
{
/* The process ID. */
int pid;
/* The status as reported by waitpid. */
int status;
/* Next in chain. */
struct simple_pid_list *next;
};
struct simple_pid_list *stopped_pids;
/* Trivial list manipulation functions to keep track of a list of new
stopped processes. */
static void
add_to_pid_list (struct simple_pid_list **listp, int pid, int status)
{
struct simple_pid_list *new_pid = xmalloc (sizeof (struct simple_pid_list));
new_pid->pid = pid;
new_pid->status = status;
new_pid->next = *listp;
*listp = new_pid;
}
static int
pull_pid_from_list (struct simple_pid_list **listp, int pid, int *statusp)
{
struct simple_pid_list **p;
for (p = listp; *p != NULL; p = &(*p)->next)
if ((*p)->pid == pid)
{
struct simple_pid_list *next = (*p)->next;
*statusp = (*p)->status;
xfree (*p);
*p = next;
return 1;
}
return 0;
}
enum stopping_threads_kind
{
/* Not stopping threads presently. */
NOT_STOPPING_THREADS,
/* Stopping threads. */
STOPPING_THREADS,
/* Stopping and suspending threads. */
STOPPING_AND_SUSPENDING_THREADS
};
/* This is set while stop_all_lwps is in effect. */
enum stopping_threads_kind stopping_threads = NOT_STOPPING_THREADS;
/* FIXME make into a target method? */
int using_threads = 1;
/* True if we're presently stabilizing threads (moving them out of
jump pads). */
static int stabilizing_threads;
/* This flag is true iff we've just created or attached to our first
inferior but it has not stopped yet. As soon as it does, we need
to call the low target's arch_setup callback. Doing this only on
the first inferior avoids reinializing the architecture on every
inferior, and avoids messing with the register caches of the
already running inferiors. NOTE: this assumes all inferiors under
control of gdbserver have the same architecture. */
static int new_inferior;
static void linux_resume_one_lwp (struct lwp_info *lwp,
int step, int signal, siginfo_t *info);
static void linux_resume (struct thread_resume *resume_info, size_t n);
static void stop_all_lwps (int suspend, struct lwp_info *except);
static void unstop_all_lwps (int unsuspend, struct lwp_info *except);
static int linux_wait_for_event (ptid_t ptid, int *wstat, int options);
static void *add_lwp (ptid_t ptid);
static int linux_stopped_by_watchpoint (void);
static void mark_lwp_dead (struct lwp_info *lwp, int wstat);
static void proceed_all_lwps (void);
static int finish_step_over (struct lwp_info *lwp);
static CORE_ADDR get_stop_pc (struct lwp_info *lwp);
static int kill_lwp (unsigned long lwpid, int signo);
static void linux_enable_event_reporting (int pid);
/* True if the low target can hardware single-step. Such targets
don't need a BREAKPOINT_REINSERT_ADDR callback. */
static int
can_hardware_single_step (void)
{
return (the_low_target.breakpoint_reinsert_addr == NULL);
}
/* True if the low target supports memory breakpoints. If so, we'll
have a GET_PC implementation. */
static int
supports_breakpoints (void)
{
return (the_low_target.get_pc != NULL);
}
/* Returns true if this target can support fast tracepoints. This
does not mean that the in-process agent has been loaded in the
inferior. */
static int
supports_fast_tracepoints (void)
{
return the_low_target.install_fast_tracepoint_jump_pad != NULL;
}
struct pending_signals
{
int signal;
siginfo_t info;
struct pending_signals *prev;
};
#ifdef HAVE_LINUX_REGSETS
static char *disabled_regsets;
static int num_regsets;
#endif
/* The read/write ends of the pipe registered as waitable file in the
event loop. */
static int linux_event_pipe[2] = { -1, -1 };
/* True if we're currently in async mode. */
#define target_is_async_p() (linux_event_pipe[0] != -1)
static void send_sigstop (struct lwp_info *lwp);
static void wait_for_sigstop (struct inferior_list_entry *entry);
/* Return non-zero if HEADER is a 64-bit ELF file. */
static int
elf_64_header_p (const Elf64_Ehdr *header, unsigned int *machine)
{
if (header->e_ident[EI_MAG0] == ELFMAG0
&& header->e_ident[EI_MAG1] == ELFMAG1
&& header->e_ident[EI_MAG2] == ELFMAG2
&& header->e_ident[EI_MAG3] == ELFMAG3)
{
*machine = header->e_machine;
return header->e_ident[EI_CLASS] == ELFCLASS64;
}
*machine = EM_NONE;
return -1;
}
/* Return non-zero if FILE is a 64-bit ELF file,
zero if the file is not a 64-bit ELF file,
and -1 if the file is not accessible or doesn't exist. */
static int
elf_64_file_p (const char *file, unsigned int *machine)
{
Elf64_Ehdr header;
int fd;
fd = open (file, O_RDONLY);
if (fd < 0)
return -1;
if (read (fd, &header, sizeof (header)) != sizeof (header))
{
close (fd);
return 0;
}
close (fd);
return elf_64_header_p (&header, machine);
}
/* Accepts an integer PID; Returns true if the executable PID is
running is a 64-bit ELF file.. */
int
linux_pid_exe_is_elf_64_file (int pid, unsigned int *machine)
{
char file[MAXPATHLEN];
sprintf (file, "/proc/%d/exe", pid);
return elf_64_file_p (file, machine);
}
static void
delete_lwp (struct lwp_info *lwp)
{
remove_thread (get_lwp_thread (lwp));
remove_inferior (&all_lwps, &lwp->head);
free (lwp->arch_private);
free (lwp);
}
/* Add a process to the common process list, and set its private
data. */
static struct process_info *
linux_add_process (int pid, int attached)
{
struct process_info *proc;
/* Is this the first process? If so, then set the arch. */
if (all_processes.head == NULL)
new_inferior = 1;
proc = add_process (pid, attached);
proc->private = xcalloc (1, sizeof (*proc->private));
if (the_low_target.new_process != NULL)
proc->private->arch_private = the_low_target.new_process ();
return proc;
}
/* Wrapper function for waitpid which handles EINTR, and emulates
__WALL for systems where that is not available. */
static int
my_waitpid (int pid, int *status, int flags)
{
int ret, out_errno;
if (debug_threads)
fprintf (stderr, "my_waitpid (%d, 0x%x)\n", pid, flags);
if (flags & __WALL)
{
sigset_t block_mask, org_mask, wake_mask;
int wnohang;
wnohang = (flags & WNOHANG) != 0;
flags &= ~(__WALL | __WCLONE);
flags |= WNOHANG;
/* Block all signals while here. This avoids knowing about
LinuxThread's signals. */
sigfillset (&block_mask);
sigprocmask (SIG_BLOCK, &block_mask, &org_mask);
/* ... except during the sigsuspend below. */
sigemptyset (&wake_mask);
while (1)
{
/* Since all signals are blocked, there's no need to check
for EINTR here. */
ret = waitpid (pid, status, flags);
out_errno = errno;
if (ret == -1 && out_errno != ECHILD)
break;
else if (ret > 0)
break;
if (flags & __WCLONE)
{
/* We've tried both flavors now. If WNOHANG is set,
there's nothing else to do, just bail out. */
if (wnohang)
break;
if (debug_threads)
fprintf (stderr, "blocking\n");
/* Block waiting for signals. */
sigsuspend (&wake_mask);
}
flags ^= __WCLONE;
}
sigprocmask (SIG_SETMASK, &org_mask, NULL);
}
else
{
do
ret = waitpid (pid, status, flags);
while (ret == -1 && errno == EINTR);
out_errno = errno;
}
if (debug_threads)
fprintf (stderr, "my_waitpid (%d, 0x%x): status(%x), %d\n",
pid, flags, status ? *status : -1, ret);
errno = out_errno;
return ret;
}
/* Handle a GNU/Linux extended wait response. If we see a clone
event, we need to add the new LWP to our list (and not report the
trap to higher layers). */
static void
handle_extended_wait (struct lwp_info *event_child, int wstat)
{
int event = wstat >> 16;
struct lwp_info *new_lwp;
if (event == PTRACE_EVENT_CLONE)
{
ptid_t ptid;
unsigned long new_pid;
int ret, status;
ptrace (PTRACE_GETEVENTMSG, lwpid_of (event_child), 0, &new_pid);
/* If we haven't already seen the new PID stop, wait for it now. */
if (!pull_pid_from_list (&stopped_pids, new_pid, &status))
{
/* The new child has a pending SIGSTOP. We can't affect it until it
hits the SIGSTOP, but we're already attached. */
ret = my_waitpid (new_pid, &status, __WALL);
if (ret == -1)
perror_with_name ("waiting for new child");
else if (ret != new_pid)
warning ("wait returned unexpected PID %d", ret);
else if (!WIFSTOPPED (status))
warning ("wait returned unexpected status 0x%x", status);
}
linux_enable_event_reporting (new_pid);
ptid = ptid_build (pid_of (event_child), new_pid, 0);
new_lwp = (struct lwp_info *) add_lwp (ptid);
add_thread (ptid, new_lwp);
/* Either we're going to immediately resume the new thread
or leave it stopped. linux_resume_one_lwp is a nop if it
thinks the thread is currently running, so set this first
before calling linux_resume_one_lwp. */
new_lwp->stopped = 1;
/* If we're suspending all threads, leave this one suspended
too. */
if (stopping_threads == STOPPING_AND_SUSPENDING_THREADS)
new_lwp->suspended = 1;
/* Normally we will get the pending SIGSTOP. But in some cases
we might get another signal delivered to the group first.
If we do get another signal, be sure not to lose it. */
if (WSTOPSIG (status) == SIGSTOP)
{
if (stopping_threads != NOT_STOPPING_THREADS)
new_lwp->stop_pc = get_stop_pc (new_lwp);
else
linux_resume_one_lwp (new_lwp, 0, 0, NULL);
}
else
{
new_lwp->stop_expected = 1;
if (stopping_threads != NOT_STOPPING_THREADS)
{
new_lwp->stop_pc = get_stop_pc (new_lwp);
new_lwp->status_pending_p = 1;
new_lwp->status_pending = status;
}
else
/* Pass the signal on. This is what GDB does - except
shouldn't we really report it instead? */
linux_resume_one_lwp (new_lwp, 0, WSTOPSIG (status), NULL);
}
/* Always resume the current thread. If we are stopping
threads, it will have a pending SIGSTOP; we may as well
collect it now. */
linux_resume_one_lwp (event_child, event_child->stepping, 0, NULL);
}
}
/* Return the PC as read from the regcache of LWP, without any
adjustment. */
static CORE_ADDR
get_pc (struct lwp_info *lwp)
{
struct thread_info *saved_inferior;
struct regcache *regcache;
CORE_ADDR pc;
if (the_low_target.get_pc == NULL)
return 0;
saved_inferior = current_inferior;
current_inferior = get_lwp_thread (lwp);
regcache = get_thread_regcache (current_inferior, 1);
pc = (*the_low_target.get_pc) (regcache);
if (debug_threads)
fprintf (stderr, "pc is 0x%lx\n", (long) pc);
current_inferior = saved_inferior;
return pc;
}
/* This function should only be called if LWP got a SIGTRAP.
The SIGTRAP could mean several things.
On i386, where decr_pc_after_break is non-zero:
If we were single-stepping this process using PTRACE_SINGLESTEP,
we will get only the one SIGTRAP (even if the instruction we
stepped over was a breakpoint). The value of $eip will be the
next instruction.
If we continue the process using PTRACE_CONT, we will get a
SIGTRAP when we hit a breakpoint. The value of $eip will be
the instruction after the breakpoint (i.e. needs to be
decremented). If we report the SIGTRAP to GDB, we must also
report the undecremented PC. If we cancel the SIGTRAP, we
must resume at the decremented PC.
(Presumably, not yet tested) On a non-decr_pc_after_break machine
with hardware or kernel single-step:
If we single-step over a breakpoint instruction, our PC will
point at the following instruction. If we continue and hit a
breakpoint instruction, our PC will point at the breakpoint
instruction. */
static CORE_ADDR
get_stop_pc (struct lwp_info *lwp)
{
CORE_ADDR stop_pc;
if (the_low_target.get_pc == NULL)
return 0;
stop_pc = get_pc (lwp);
if (WSTOPSIG (lwp->last_status) == SIGTRAP
&& !lwp->stepping
&& !lwp->stopped_by_watchpoint
&& lwp->last_status >> 16 == 0)
stop_pc -= the_low_target.decr_pc_after_break;
if (debug_threads)
fprintf (stderr, "stop pc is 0x%lx\n", (long) stop_pc);
return stop_pc;
}
static void *
add_lwp (ptid_t ptid)
{
struct lwp_info *lwp;
lwp = (struct lwp_info *) xmalloc (sizeof (*lwp));
memset (lwp, 0, sizeof (*lwp));
lwp->head.id = ptid;
if (the_low_target.new_thread != NULL)
lwp->arch_private = the_low_target.new_thread ();
add_inferior_to_list (&all_lwps, &lwp->head);
return lwp;
}
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args. */
static int
linux_create_inferior (char *program, char **allargs)
{
#ifdef HAVE_PERSONALITY
int personality_orig = 0, personality_set = 0;
#endif
struct lwp_info *new_lwp;
int pid;
ptid_t ptid;
#ifdef HAVE_PERSONALITY
if (disable_randomization)
{
errno = 0;
personality_orig = personality (0xffffffff);
if (errno == 0 && !(personality_orig & ADDR_NO_RANDOMIZE))
{
personality_set = 1;
personality (personality_orig | ADDR_NO_RANDOMIZE);
}
if (errno != 0 || (personality_set
&& !(personality (0xffffffff) & ADDR_NO_RANDOMIZE)))
warning ("Error disabling address space randomization: %s",
strerror (errno));
}
#endif
#if defined(__UCLIBC__) && defined(HAS_NOMMU)
pid = vfork ();
#else
pid = fork ();
#endif
if (pid < 0)
perror_with_name ("fork");
if (pid == 0)
{
ptrace (PTRACE_TRACEME, 0, 0, 0);
#ifndef __ANDROID__ /* Bionic doesn't use SIGRTMIN the way glibc does. */
signal (__SIGRTMIN + 1, SIG_DFL);
#endif
setpgid (0, 0);
/* If gdbserver is connected to gdb via stdio, redirect the inferior's
stdout to stderr so that inferior i/o doesn't corrupt the connection.
Also, redirect stdin to /dev/null. */
if (remote_connection_is_stdio ())
{
close (0);
open ("/dev/null", O_RDONLY);
dup2 (2, 1);
if (write (2, "stdin/stdout redirected\n",
sizeof ("stdin/stdout redirected\n") - 1) < 0)
/* Errors ignored. */;
}
execv (program, allargs);
if (errno == ENOENT)
execvp (program, allargs);
fprintf (stderr, "Cannot exec %s: %s.\n", program,
strerror (errno));
fflush (stderr);
_exit (0177);
}
#ifdef HAVE_PERSONALITY
if (personality_set)
{
errno = 0;
personality (personality_orig);
if (errno != 0)
warning ("Error restoring address space randomization: %s",
strerror (errno));
}
#endif
linux_add_process (pid, 0);
ptid = ptid_build (pid, pid, 0);
new_lwp = add_lwp (ptid);
add_thread (ptid, new_lwp);
new_lwp->must_set_ptrace_flags = 1;
return pid;
}
/* Attach to an inferior process. */
static void
linux_attach_lwp_1 (unsigned long lwpid, int initial)
{
ptid_t ptid;
struct lwp_info *new_lwp;
if (ptrace (PTRACE_ATTACH, lwpid, 0, 0) != 0)
{
struct buffer buffer;
if (!initial)
{
/* If we fail to attach to an LWP, just warn. */
fprintf (stderr, "Cannot attach to lwp %ld: %s (%d)\n", lwpid,
strerror (errno), errno);
fflush (stderr);
return;
}
/* If we fail to attach to a process, report an error. */
buffer_init (&buffer);
linux_ptrace_attach_warnings (lwpid, &buffer);
buffer_grow_str0 (&buffer, "");
error ("%sCannot attach to lwp %ld: %s (%d)", buffer_finish (&buffer),
lwpid, strerror (errno), errno);
}
if (initial)
/* If lwp is the tgid, we handle adding existing threads later.
Otherwise we just add lwp without bothering about any other
threads. */
ptid = ptid_build (lwpid, lwpid, 0);
else
{
/* Note that extracting the pid from the current inferior is
safe, since we're always called in the context of the same
process as this new thread. */
int pid = pid_of (get_thread_lwp (current_inferior));
ptid = ptid_build (pid, lwpid, 0);
}
new_lwp = (struct lwp_info *) add_lwp (ptid);
add_thread (ptid, new_lwp);
/* We need to wait for SIGSTOP before being able to make the next
ptrace call on this LWP. */
new_lwp->must_set_ptrace_flags = 1;
if (linux_proc_pid_is_stopped (lwpid))
{
if (debug_threads)
fprintf (stderr,
"Attached to a stopped process\n");
/* The process is definitely stopped. It is in a job control
stop, unless the kernel predates the TASK_STOPPED /
TASK_TRACED distinction, in which case it might be in a
ptrace stop. Make sure it is in a ptrace stop; from there we
can kill it, signal it, et cetera.
First make sure there is a pending SIGSTOP. Since we are
already attached, the process can not transition from stopped
to running without a PTRACE_CONT; so we know this signal will
go into the queue. The SIGSTOP generated by PTRACE_ATTACH is
probably already in the queue (unless this kernel is old
enough to use TASK_STOPPED for ptrace stops); but since
SIGSTOP is not an RT signal, it can only be queued once. */
kill_lwp (lwpid, SIGSTOP);
/* Finally, resume the stopped process. This will deliver the
SIGSTOP (or a higher priority signal, just like normal
PTRACE_ATTACH), which we'll catch later on. */
ptrace (PTRACE_CONT, lwpid, 0, 0);
}
/* The next time we wait for this LWP we'll see a SIGSTOP as PTRACE_ATTACH
brings it to a halt.
There are several cases to consider here:
1) gdbserver has already attached to the process and is being notified
of a new thread that is being created.
In this case we should ignore that SIGSTOP and resume the
process. This is handled below by setting stop_expected = 1,
and the fact that add_thread sets last_resume_kind ==
resume_continue.
2) This is the first thread (the process thread), and we're attaching
to it via attach_inferior.
In this case we want the process thread to stop.
This is handled by having linux_attach set last_resume_kind ==
resume_stop after we return.
If the pid we are attaching to is also the tgid, we attach to and
stop all the existing threads. Otherwise, we attach to pid and
ignore any other threads in the same group as this pid.
3) GDB is connecting to gdbserver and is requesting an enumeration of all
existing threads.
In this case we want the thread to stop.
FIXME: This case is currently not properly handled.
We should wait for the SIGSTOP but don't. Things work apparently
because enough time passes between when we ptrace (ATTACH) and when
gdb makes the next ptrace call on the thread.
On the other hand, if we are currently trying to stop all threads, we
should treat the new thread as if we had sent it a SIGSTOP. This works
because we are guaranteed that the add_lwp call above added us to the
end of the list, and so the new thread has not yet reached
wait_for_sigstop (but will). */
new_lwp->stop_expected = 1;
}
void
linux_attach_lwp (unsigned long lwpid)
{
linux_attach_lwp_1 (lwpid, 0);
}
/* Attach to PID. If PID is the tgid, attach to it and all
of its threads. */
static int
linux_attach (unsigned long pid)
{
/* Attach to PID. We will check for other threads
soon. */
linux_attach_lwp_1 (pid, 1);
linux_add_process (pid, 1);
if (!non_stop)
{
struct thread_info *thread;
/* Don't ignore the initial SIGSTOP if we just attached to this
process. It will be collected by wait shortly. */
thread = find_thread_ptid (ptid_build (pid, pid, 0));
thread->last_resume_kind = resume_stop;
}
if (linux_proc_get_tgid (pid) == pid)
{
DIR *dir;
char pathname[128];
sprintf (pathname, "/proc/%ld/task", pid);
dir = opendir (pathname);
if (!dir)
{
fprintf (stderr, "Could not open /proc/%ld/task.\n", pid);
fflush (stderr);
}
else
{
/* At this point we attached to the tgid. Scan the task for
existing threads. */
unsigned long lwp;
int new_threads_found;
int iterations = 0;
struct dirent *dp;
while (iterations < 2)
{
new_threads_found = 0;
/* Add all the other threads. While we go through the
threads, new threads may be spawned. Cycle through
the list of threads until we have done two iterations without
finding new threads. */
while ((dp = readdir (dir)) != NULL)
{
/* Fetch one lwp. */
lwp = strtoul (dp->d_name, NULL, 10);
/* Is this a new thread? */
if (lwp
&& find_thread_ptid (ptid_build (pid, lwp, 0)) == NULL)
{
linux_attach_lwp_1 (lwp, 0);
new_threads_found++;
if (debug_threads)
fprintf (stderr, "\
Found and attached to new lwp %ld\n", lwp);
}
}
if (!new_threads_found)
iterations++;
else
iterations = 0;
rewinddir (dir);
}
closedir (dir);
}
}
return 0;
}
struct counter
{
int pid;
int count;
};
static int
second_thread_of_pid_p (struct inferior_list_entry *entry, void *args)
{
struct counter *counter = args;
if (ptid_get_pid (entry->id) == counter->pid)
{
if (++counter->count > 1)
return 1;
}
return 0;
}
static int
last_thread_of_process_p (struct thread_info *thread)
{
ptid_t ptid = ((struct inferior_list_entry *)thread)->id;
int pid = ptid_get_pid (ptid);
struct counter counter = { pid , 0 };
return (find_inferior (&all_threads,
second_thread_of_pid_p, &counter) == NULL);
}
/* Kill LWP. */
static void
linux_kill_one_lwp (struct lwp_info *lwp)
{
int pid = lwpid_of (lwp);
/* PTRACE_KILL is unreliable. After stepping into a signal handler,
there is no signal context, and ptrace(PTRACE_KILL) (or
ptrace(PTRACE_CONT, SIGKILL), pretty much the same) acts like
ptrace(CONT, pid, 0,0) and just resumes the tracee. A better
alternative is to kill with SIGKILL. We only need one SIGKILL
per process, not one for each thread. But since we still support
linuxthreads, and we also support debugging programs using raw
clone without CLONE_THREAD, we send one for each thread. For
years, we used PTRACE_KILL only, so we're being a bit paranoid
about some old kernels where PTRACE_KILL might work better
(dubious if there are any such, but that's why it's paranoia), so
we try SIGKILL first, PTRACE_KILL second, and so we're fine
everywhere. */
errno = 0;
kill (pid, SIGKILL);
if (debug_threads)
fprintf (stderr,
"LKL: kill (SIGKILL) %s, 0, 0 (%s)\n",
target_pid_to_str (ptid_of (lwp)),
errno ? strerror (errno) : "OK");
errno = 0;
ptrace (PTRACE_KILL, pid, 0, 0);
if (debug_threads)
fprintf (stderr,
"LKL: PTRACE_KILL %s, 0, 0 (%s)\n",
target_pid_to_str (ptid_of (lwp)),
errno ? strerror (errno) : "OK");
}
/* Callback for `find_inferior'. Kills an lwp of a given process,
except the leader. */
static int
kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
{
struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int wstat;
int pid = * (int *) args;
if (ptid_get_pid (entry->id) != pid)
return 0;
/* We avoid killing the first thread here, because of a Linux kernel (at
least 2.6.0-test7 through 2.6.8-rc4) bug; if we kill the parent before
the children get a chance to be reaped, it will remain a zombie
forever. */
if (lwpid_of (lwp) == pid)
{
if (debug_threads)
fprintf (stderr, "lkop: is last of process %s\n",
target_pid_to_str (entry->id));
return 0;
}
do
{
linux_kill_one_lwp (lwp);
/* Make sure it died. The loop is most likely unnecessary. */
pid = linux_wait_for_event (lwp->head.id, &wstat, __WALL);
} while (pid > 0 && WIFSTOPPED (wstat));
return 0;
}
static int
linux_kill (int pid)
{
struct process_info *process;
struct lwp_info *lwp;
int wstat;
int lwpid;
process = find_process_pid (pid);
if (process == NULL)
return -1;
/* If we're killing a running inferior, make sure it is stopped
first, as PTRACE_KILL will not work otherwise. */
stop_all_lwps (0, NULL);
find_inferior (&all_threads, kill_one_lwp_callback , &pid);
/* See the comment in linux_kill_one_lwp. We did not kill the first
thread in the list, so do so now. */
lwp = find_lwp_pid (pid_to_ptid (pid));
if (lwp == NULL)
{
if (debug_threads)
fprintf (stderr, "lk_1: cannot find lwp %ld, for pid: %d\n",
lwpid_of (lwp), pid);
}
else
{
if (debug_threads)
fprintf (stderr, "lk_1: killing lwp %ld, for pid: %d\n",
lwpid_of (lwp), pid);
do
{
linux_kill_one_lwp (lwp);
/* Make sure it died. The loop is most likely unnecessary. */
lwpid = linux_wait_for_event (lwp->head.id, &wstat, __WALL);
} while (lwpid > 0 && WIFSTOPPED (wstat));
}
the_target->mourn (process);
/* Since we presently can only stop all lwps of all processes, we
need to unstop lwps of other processes. */
unstop_all_lwps (0, NULL);
return 0;
}
/* Get pending signal of THREAD, for detaching purposes. This is the
signal the thread last stopped for, which we need to deliver to the
thread when detaching, otherwise, it'd be suppressed/lost. */
static int
get_detach_signal (struct thread_info *thread)
{
enum gdb_signal signo = GDB_SIGNAL_0;
int status;
struct lwp_info *lp = get_thread_lwp (thread);
if (lp->status_pending_p)
status = lp->status_pending;
else
{
/* If the thread had been suspended by gdbserver, and it stopped
cleanly, then it'll have stopped with SIGSTOP. But we don't
want to deliver that SIGSTOP. */
if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
|| thread->last_status.value.sig == GDB_SIGNAL_0)
return 0;
/* Otherwise, we may need to deliver the signal we
intercepted. */
status = lp->last_status;
}
if (!WIFSTOPPED (status))
{
if (debug_threads)
fprintf (stderr,
"GPS: lwp %s hasn't stopped: no pending signal\n",
target_pid_to_str (ptid_of (lp)));
return 0;
}
/* Extended wait statuses aren't real SIGTRAPs. */
if (WSTOPSIG (status) == SIGTRAP && status >> 16 != 0)
{
if (debug_threads)
fprintf (stderr,
"GPS: lwp %s had stopped with extended "
"status: no pending signal\n",
target_pid_to_str (ptid_of (lp)));
return 0;
}
signo = gdb_signal_from_host (WSTOPSIG (status));
if (program_signals_p && !program_signals[signo])
{
if (debug_threads)
fprintf (stderr,
"GPS: lwp %s had signal %s, but it is in nopass state\n",
target_pid_to_str (ptid_of (lp)),
gdb_signal_to_string (signo));
return 0;
}
else if (!program_signals_p
/* If we have no way to know which signals GDB does not
want to have passed to the program, assume
SIGTRAP/SIGINT, which is GDB's default. */
&& (signo == GDB_SIGNAL_TRAP || signo == GDB_SIGNAL_INT))
{
if (debug_threads)
fprintf (stderr,
"GPS: lwp %s had signal %s, "
"but we don't know if we should pass it. Default to not.\n",
target_pid_to_str (ptid_of (lp)),
gdb_signal_to_string (signo));
return 0;
}
else
{
if (debug_threads)
fprintf (stderr,
"GPS: lwp %s has pending signal %s: delivering it.\n",
target_pid_to_str (ptid_of (lp)),
gdb_signal_to_string (signo));
return WSTOPSIG (status);
}
}
static int
linux_detach_one_lwp (struct inferior_list_entry *entry, void *args)
{
struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int pid = * (int *) args;
int sig;
if (ptid_get_pid (entry->id) != pid)
return 0;
/* If there is a pending SIGSTOP, get rid of it. */
if (lwp->stop_expected)
{
if (debug_threads)
fprintf (stderr,
"Sending SIGCONT to %s\n",
target_pid_to_str (ptid_of (lwp)));
kill_lwp (lwpid_of (lwp), SIGCONT);
lwp->stop_expected = 0;
}
/* Flush any pending changes to the process's registers. */
regcache_invalidate_one ((struct inferior_list_entry *)
get_lwp_thread (lwp));
/* Pass on any pending signal for this thread. */
sig = get_detach_signal (thread);
/* Finally, let it resume. */
if (the_low_target.prepare_to_resume != NULL)
the_low_target.prepare_to_resume (lwp);
if (ptrace (PTRACE_DETACH, lwpid_of (lwp), 0,
(PTRACE_ARG4_TYPE) (long) sig) < 0)
error (_("Can't detach %s: %s"),
target_pid_to_str (ptid_of (lwp)),
strerror (errno));
delete_lwp (lwp);
return 0;
}
static int
linux_detach (int pid)
{
struct process_info *process;
process = find_process_pid (pid);
if (process == NULL)
return -1;
/* Stop all threads before detaching. First, ptrace requires that
the thread is stopped to sucessfully detach. Second, thread_db
may need to uninstall thread event breakpoints from memory, which
only works with a stopped process anyway. */
stop_all_lwps (0, NULL);
#ifdef USE_THREAD_DB
thread_db_detach (process);
#endif
/* Stabilize threads (move out of jump pads). */
stabilize_threads ();
find_inferior (&all_threads, linux_detach_one_lwp, &pid);
the_target->mourn (process);
/* Since we presently can only stop all lwps of all processes, we
need to unstop lwps of other processes. */
unstop_all_lwps (0, NULL);
return 0;
}
/* Remove all LWPs that belong to process PROC from the lwp list. */
static int
delete_lwp_callback (struct inferior_list_entry *entry, void *proc)
{
struct lwp_info *lwp = (struct lwp_info *) entry;
struct process_info *process = proc;
if (pid_of (lwp) == pid_of (process))
delete_lwp (lwp);
return 0;
}
static void
linux_mourn (struct process_info *process)
{
struct process_info_private *priv;
#ifdef USE_THREAD_DB
thread_db_mourn (process);
#endif
find_inferior (&all_lwps, delete_lwp_callback, process);
/* Freeing all private data. */
priv = process->private;
free (priv->arch_private);
free (priv);
process->private = NULL;
remove_process (process);
}
static void
linux_join (int pid)
{
int status, ret;
do {
ret = my_waitpid (pid, &status, 0);
if (WIFEXITED (status) || WIFSIGNALED (status))
break;
} while (ret != -1 || errno != ECHILD);
}
/* Return nonzero if the given thread is still alive. */
static int
linux_thread_alive (ptid_t ptid)
{
struct lwp_info *lwp = find_lwp_pid (ptid);
/* We assume we always know if a thread exits. If a whole process
exited but we still haven't been able to report it to GDB, we'll
hold on to the last lwp of the dead process. */
if (lwp != NULL)
return !lwp->dead;
else
return 0;
}
/* Return 1 if this lwp has an interesting status pending. */
static int
status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
{
struct lwp_info *lwp = (struct lwp_info *) entry;
ptid_t ptid = * (ptid_t *) arg;
struct thread_info *thread;
/* Check if we're only interested in events from a specific process
or its lwps. */
if (!ptid_equal (minus_one_ptid, ptid)
&& ptid_get_pid (ptid) != ptid_get_pid (lwp->head.id))
return 0;
thread = get_lwp_thread (lwp);
/* If we got a `vCont;t', but we haven't reported a stop yet, do
report any status pending the LWP may have. */
if (thread->last_resume_kind == resume_stop
&& thread->last_status.kind != TARGET_WAITKIND_IGNORE)
return 0;
return lwp->status_pending_p;
}
static int
same_lwp (struct inferior_list_entry *entry, void *data)
{
ptid_t ptid = *(ptid_t *) data;
int lwp;
if (ptid_get_lwp (ptid) != 0)
lwp = ptid_get_lwp (ptid);
else
lwp = ptid_get_pid (ptid);
if (ptid_get_lwp (entry->id) == lwp)
return 1;
return 0;
}
struct lwp_info *
find_lwp_pid (ptid_t ptid)
{
return (struct lwp_info*) find_inferior (&all_lwps, same_lwp, &ptid);
}
static struct lwp_info *
linux_wait_for_lwp (ptid_t ptid, int *wstatp, int options)
{
int ret;
int to_wait_for = -1;
struct lwp_info *child = NULL;
if (debug_threads)
fprintf (stderr, "linux_wait_for_lwp: %s\n", target_pid_to_str (ptid));
if (ptid_equal (ptid, minus_one_ptid))
to_wait_for = -1; /* any child */
else
to_wait_for = ptid_get_lwp (ptid); /* this lwp only */
options |= __WALL;
retry:
ret = my_waitpid (to_wait_for, wstatp, options);
if (ret == 0 || (ret == -1 && errno == ECHILD && (options & WNOHANG)))
return NULL;
else if (ret == -1)
perror_with_name ("waitpid");
if (debug_threads
&& (!WIFSTOPPED (*wstatp)
|| (WSTOPSIG (*wstatp) != 32
&& WSTOPSIG (*wstatp) != 33)))
fprintf (stderr, "Got an event from %d (%x)\n", ret, *wstatp);
child = find_lwp_pid (pid_to_ptid (ret));
/* If we didn't find a process, one of two things presumably happened:
- A process we started and then detached from has exited. Ignore it.
- A process we are controlling has forked and the new child's stop
was reported to us by the kernel. Save its PID. */
if (child == NULL && WIFSTOPPED (*wstatp))
{
add_to_pid_list (&stopped_pids, ret, *wstatp);
goto retry;
}
else if (child == NULL)
goto retry;
child->stopped = 1;
child->last_status = *wstatp;
/* Architecture-specific setup after inferior is running.
This needs to happen after we have attached to the inferior
and it is stopped for the first time, but before we access
any inferior registers. */
if (new_inferior)
{
the_low_target.arch_setup ();
#ifdef HAVE_LINUX_REGSETS
memset (disabled_regsets, 0, num_regsets);
#endif
new_inferior = 0;
}
/* Fetch the possibly triggered data watchpoint info and store it in
CHILD.
On some archs, like x86, that use debug registers to set
watchpoints, it's possible that the way to know which watched
address trapped, is to check the register that is used to select
which address to watch. Problem is, between setting the
watchpoint and reading back which data address trapped, the user
may change the set of watchpoints, and, as a consequence, GDB
changes the debug registers in the inferior. To avoid reading
back a stale stopped-data-address when that happens, we cache in
LP the fact that a watchpoint trapped, and the corresponding data
address, as soon as we see CHILD stop with a SIGTRAP. If GDB
changes the debug registers meanwhile, we have the cached data we
can rely on. */
if (WIFSTOPPED (*wstatp) && WSTOPSIG (*wstatp) == SIGTRAP)
{
if (the_low_target.stopped_by_watchpoint == NULL)
{
child->stopped_by_watchpoint = 0;
}
else
{
struct thread_info *saved_inferior;
saved_inferior = current_inferior;
current_inferior = get_lwp_thread (child);
child->stopped_by_watchpoint
= the_low_target.stopped_by_watchpoint ();
if (child->stopped_by_watchpoint)
{
if (the_low_target.stopped_data_address != NULL)
child->stopped_data_address
= the_low_target.stopped_data_address ();
else
child->stopped_data_address = 0;
}
current_inferior = saved_inferior;
}
}
/* Store the STOP_PC, with adjustment applied. This depends on the
architecture being defined already (so that CHILD has a valid
regcache), and on LAST_STATUS being set (to check for SIGTRAP or
not). */
if (WIFSTOPPED (*wstatp))
child->stop_pc = get_stop_pc (child);
if (debug_threads
&& WIFSTOPPED (*wstatp)
&& the_low_target.get_pc != NULL)
{
struct thread_info *saved_inferior = current_inferior;
struct regcache *regcache;
CORE_ADDR pc;
current_inferior = get_lwp_thread (child);
regcache = get_thread_regcache (current_inferior, 1);
pc = (*the_low_target.get_pc) (regcache);
fprintf (stderr, "linux_wait_for_lwp: pc is 0x%lx\n", (long) pc);
current_inferior = saved_inferior;
}
return child;
}
/* This function should only be called if the LWP got a SIGTRAP.
Handle any tracepoint steps or hits. Return true if a tracepoint
event was handled, 0 otherwise. */
static int
handle_tracepoints (struct lwp_info *lwp)
{
struct thread_info *tinfo = get_lwp_thread (lwp);
int tpoint_related_event = 0;
/* If this tracepoint hit causes a tracing stop, we'll immediately
uninsert tracepoints. To do this, we temporarily pause all
threads, unpatch away, and then unpause threads. We need to make
sure the unpausing doesn't resume LWP too. */
lwp->suspended++;
/* And we need to be sure that any all-threads-stopping doesn't try
to move threads out of the jump pads, as it could deadlock the
inferior (LWP could be in the jump pad, maybe even holding the
lock.) */
/* Do any necessary step collect actions. */
tpoint_related_event |= tracepoint_finished_step (tinfo, lwp->stop_pc);
tpoint_related_event |= handle_tracepoint_bkpts (tinfo, lwp->stop_pc);
/* See if we just hit a tracepoint and do its main collect
actions. */
tpoint_related_event |= tracepoint_was_hit (tinfo, lwp->stop_pc);
lwp->suspended--;
gdb_assert (lwp->suspended == 0);
gdb_assert (!stabilizing_threads || lwp->collecting_fast_tracepoint);
if (tpoint_related_event)
{
if (debug_threads)
fprintf (stderr, "got a tracepoint event\n");
return 1;
}
return 0;
}
/* Convenience wrapper. Returns true if LWP is presently collecting a
fast tracepoint. */
static int
linux_fast_tracepoint_collecting (struct lwp_info *lwp,
struct fast_tpoint_collect_status *status)
{
CORE_ADDR thread_area;
if (the_low_target.get_thread_area == NULL)
return 0;
/* Get the thread area address. This is used to recognize which
thread is which when tracing with the in-process agent library.
We don't read anything from the address, and treat it as opaque;
it's the address itself that we assume is unique per-thread. */
if ((*the_low_target.get_thread_area) (lwpid_of (lwp), &thread_area) == -1)
return 0;
return fast_tracepoint_collecting (thread_area, lwp->stop_pc, status);
}
/* The reason we resume in the caller, is because we want to be able
to pass lwp->status_pending as WSTAT, and we need to clear
status_pending_p before resuming, otherwise, linux_resume_one_lwp
refuses to resume. */
static int
maybe_move_out_of_jump_pad (struct lwp_info *lwp, int *wstat)
{
struct thread_info *saved_inferior;
saved_inferior = current_inferior;
current_inferior = get_lwp_thread (lwp);
if ((wstat == NULL
|| (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) != SIGTRAP))
&& supports_fast_tracepoints ()
&& agent_loaded_p ())
{
struct fast_tpoint_collect_status status;
int r;
if (debug_threads)
fprintf (stderr, "\
Checking whether LWP %ld needs to move out of the jump pad.\n",
lwpid_of (lwp));
r = linux_fast_tracepoint_collecting (lwp, &status);
if (wstat == NULL
|| (WSTOPSIG (*wstat) != SIGILL
&& WSTOPSIG (*wstat) != SIGFPE
&& WSTOPSIG (*wstat) != SIGSEGV
&& WSTOPSIG (*wstat) != SIGBUS))
{
lwp->collecting_fast_tracepoint = r;
if (r != 0)
{
if (r == 1 && lwp->exit_jump_pad_bkpt == NULL)
{
/* Haven't executed the original instruction yet.
Set breakpoint there, and wait till it's hit,
then single-step until exiting the jump pad. */
lwp->exit_jump_pad_bkpt
= set_breakpoint_at (status.adjusted_insn_addr, NULL);
}
if (debug_threads)
fprintf (stderr, "\
Checking whether LWP %ld needs to move out of the jump pad...it does\n",
lwpid_of (lwp));
current_inferior = saved_inferior;
return 1;
}
}
else
{
/* If we get a synchronous signal while collecting, *and*
while executing the (relocated) original instruction,
reset the PC to point at the tpoint address, before
reporting to GDB. Otherwise, it's an IPA lib bug: just
report the signal to GDB, and pray for the best. */
lwp->collecting_fast_tracepoint = 0;
if (r != 0
&& (status.adjusted_insn_addr <= lwp->stop_pc
&& lwp->stop_pc < status.adjusted_insn_addr_end))
{
siginfo_t info;
struct regcache *regcache;
/* The si_addr on a few signals references the address
of the faulting instruction. Adjust that as
well. */
if ((WSTOPSIG (*wstat) == SIGILL
|| WSTOPSIG (*wstat) == SIGFPE
|| WSTOPSIG (*wstat) == SIGBUS
|| WSTOPSIG (*wstat) == SIGSEGV)
&& ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &info) == 0
/* Final check just to make sure we don't clobber
the siginfo of non-kernel-sent signals. */
&& (uintptr_t) info.si_addr == lwp->stop_pc)
{
info.si_addr = (void *) (uintptr_t) status.tpoint_addr;
ptrace (PTRACE_SETSIGINFO, lwpid_of (lwp), 0, &info);
}
regcache = get_thread_regcache (get_lwp_thread (lwp), 1);
(*the_low_target.set_pc) (regcache, status.tpoint_addr);
lwp->stop_pc = status.tpoint_addr;
/* Cancel any fast tracepoint lock this thread was
holding. */
force_unlock_trace_buffer ();
}
if (lwp->exit_jump_pad_bkpt != NULL)
{
if (debug_threads)
fprintf (stderr,
"Cancelling fast exit-jump-pad: removing bkpt. "
"stopping all threads momentarily.\n");
stop_all_lwps (1, lwp);
cancel_breakpoints ();
delete_breakpoint (lwp->exit_jump_pad_bkpt);
lwp->exit_jump_pad_bkpt = NULL;
unstop_all_lwps (1, lwp);
gdb_assert (lwp->suspended >= 0);
}
}
}
if (debug_threads)
fprintf (stderr, "\
Checking whether LWP %ld needs to move out of the jump pad...no\n",
lwpid_of (lwp));
current_inferior = saved_inferior;
return 0;
}
/* Enqueue one signal in the "signals to report later when out of the
jump pad" list. */
static void
enqueue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
{
struct pending_signals *p_sig;
if (debug_threads)
fprintf (stderr, "\
Deferring signal %d for LWP %ld.\n", WSTOPSIG (*wstat), lwpid_of (lwp));
if (debug_threads)
{
struct pending_signals *sig;
for (sig = lwp->pending_signals_to_report;
sig != NULL;
sig = sig->prev)
fprintf (stderr,
" Already queued %d\n",
sig->signal);
fprintf (stderr, " (no more currently queued signals)\n");
}
/* Don't enqueue non-RT signals if they are already in the deferred
queue. (SIGSTOP being the easiest signal to see ending up here
twice) */
if (WSTOPSIG (*wstat) < __SIGRTMIN)
{
struct pending_signals *sig;
for (sig = lwp->pending_signals_to_report;
sig != NULL;
sig = sig->prev)
{
if (sig->signal == WSTOPSIG (*wstat))
{
if (debug_threads)
fprintf (stderr,
"Not requeuing already queued non-RT signal %d"
" for LWP %ld\n",
sig->signal,
lwpid_of (lwp));
return;
}
}
}
p_sig = xmalloc (sizeof (*p_sig));
p_sig->prev = lwp->pending_signals_to_report;
p_sig->signal = WSTOPSIG (*wstat);
memset (&p_sig->info, 0, sizeof (siginfo_t));
ptrace (PTRACE_GETSIGINFO, lwpid_of (lwp), 0, &p_sig->info);
lwp->pending_signals_to_report = p_sig;
}
/* Dequeue one signal from the "signals to report later when out of
the jump pad" list. */
static int
dequeue_one_deferred_signal (struct lwp_info *lwp, int *wstat)
{
if (lwp->pending_signals_to_report != NULL)
{
struct pending_signals **p_sig;
p_sig = &lwp->pending_signals_to_report;
while ((*p_sig)->prev != NULL)
p_sig = &(*p_sig)->prev;
*wstat = W_STOPCODE ((*p_sig)->signal);
if ((*p_sig)->info.si_signo != 0)
ptrace (PTRACE_SETSIGINFO, lwpid_of (lwp), 0, &(*p_sig)->info);
free (*p_sig);
*p_sig = NULL;
if (debug_threads)
fprintf (stderr, "Reporting deferred signal %d for LWP %ld.\n",
WSTOPSIG (*wstat), lwpid_of (lwp));
if (debug_threads)
{
struct pending_signals *sig;
for (sig = lwp->pending_signals_to_report;
sig != NULL;
sig = sig->prev)
fprintf (stderr,
" Still queued %d\n",
sig->signal);
fprintf (stderr, " (no more queued signals)\n");
}
return 1;
}
return 0;
}
/* Arrange for a breakpoint to be hit 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 this LWP,
and this breakpoint will trap again. */
static int
cancel_breakpoint (struct lwp_info *lwp)
{
struct thread_info *saved_inferior;
/* There's nothing to do if we don't support breakpoints. */
if (!supports_breakpoints ())
return 0;
/* breakpoint_at reads from current inferior. */
saved_inferior = current_inferior;
current_inferior = get_lwp_thread (lwp);
if ((*the_low_target.breakpoint_at) (lwp->stop_pc))
{
if (debug_threads)
fprintf (stderr,
"CB: Push back breakpoint for %s\n",
target_pid_to_str (ptid_of (lwp)));
/* Back up the PC if necessary. */
if (the_low_target.decr_pc_after_break)
{
struct regcache *regcache
= get_thread_regcache (current_inferior, 1);
(*the_low_target.set_pc) (regcache, lwp->stop_pc);
}
current_inferior = saved_inferior;
return 1;
}
else
{
if (debug_threads)
fprintf (stderr,
"CB: No breakpoint found at %s for [%s]\n",
paddress (lwp->stop_pc),
target_pid_to_str (ptid_of (lwp)));
}
current_inferior = saved_inferior;
return 0;
}
/* When the event-loop is doing a step-over, this points at the thread
being stepped. */
ptid_t step_over_bkpt;
/* Wait for an event from child PID. If PID is -1, wait for any
child. Store the stop status through the status pointer WSTAT.
OPTIONS is passed to the waitpid call. Return 0 if no child stop
event was found and OPTIONS contains WNOHANG. Return the PID of
the stopped child otherwise. */
static int
linux_wait_for_event (ptid_t ptid, int *wstat, int options)
{
struct lwp_info *event_child, *requested_child;
ptid_t wait_ptid;
event_child = NULL;
requested_child = NULL;
/* Check for a lwp with a pending status. */
if (ptid_equal (ptid, minus_one_ptid) || ptid_is_pid (ptid))
{
event_child = (struct lwp_info *)
find_inferior (&all_lwps, status_pending_p_callback, &ptid);
if (debug_threads && event_child)
fprintf (stderr, "Got a pending child %ld\n", lwpid_of (event_child));
}
else
{
requested_child = find_lwp_pid (ptid);
if (stopping_threads == NOT_STOPPING_THREADS
&& requested_child->status_pending_p
&& requested_child->collecting_fast_tracepoint)
{
enqueue_one_deferred_signal (requested_child,
&requested_child->status_pending);
requested_child->status_pending_p = 0;
requested_child->status_pending = 0;
linux_resume_one_lwp (requested_child, 0, 0, NULL);
}
if (requested_child->suspended
&& requested_child->status_pending_p)
fatal ("requesting an event out of a suspended child?");
if (requested_child->status_pending_p)
event_child = requested_child;
}
if (event_child != NULL)
{
if (debug_threads)
fprintf (stderr, "Got an event from pending child %ld (%04x)\n",
lwpid_of (event_child), event_child->status_pending);
*wstat = event_child->status_pending;
event_child->status_pending_p = 0;
event_child->status_pending = 0;
current_inferior = get_lwp_thread (event_child);
return lwpid_of (event_child);
}
if (ptid_is_pid (ptid))
{
/* A request to wait for a specific tgid. This is not possible
with waitpid, so instead, we wait for any child, and leave
children we're not interested in right now with a pending
status to report later. */
wait_ptid = minus_one_ptid;
}
else
wait_ptid = ptid;
/* We only enter this loop if no process has a pending wait status. Thus
any action taken in response to a wait status inside this loop is
responding as soon as we detect the status, not after any pending
events. */
while (1)
{
event_child = linux_wait_for_lwp (wait_ptid, wstat, options);
if ((options & WNOHANG) && event_child == NULL)
{
if (debug_threads)
fprintf (stderr, "WNOHANG set, no event found\n");
return 0;
}
if (event_child == NULL)
error ("event from unknown child");
if (ptid_is_pid (ptid)
&& ptid_get_pid (ptid) != ptid_get_pid (ptid_of (event_child)))
{
if (! WIFSTOPPED (*wstat))
mark_lwp_dead (event_child, *wstat);
else
{
event_child->status_pending_p = 1;
event_child->status_pending = *wstat;
}
continue;
}
current_inferior = get_lwp_thread (event_child);
/* Check for thread exit. */
if (! WIFSTOPPED (*wstat))
{
if (debug_threads)
fprintf (stderr, "LWP %ld exiting\n", lwpid_of (event_child));
/* If the last thread is exiting, just return. */
if (last_thread_of_process_p (current_inferior))
{
if (debug_threads)
fprintf (stderr, "LWP %ld is last lwp of process\n",
lwpid_of (event_child));
return lwpid_of (event_child);
}
if (!non_stop)
{
current_inferior = (struct thread_info *) all_threads.head;
if (debug_threads)
fprintf (stderr, "Current inferior is now %ld\n",
lwpid_of (get_thread_lwp (current_inferior)));
}
else
{
current_inferior = NULL;
if (debug_threads)
fprintf (stderr, "Current inferior is now <NULL>\n");
}
/* If we were waiting for this particular child to do something...
well, it did something. */
if (requested_child != NULL)
{
int lwpid = lwpid_of (event_child);
/* Cancel the step-over operation --- the thread that
started it is gone. */
if (finish_step_over (event_child))
unstop_all_lwps (1, event_child);
delete_lwp (event_child);
return lwpid;
}
delete_lwp (event_child);
/* Wait for a more interesting event. */
continue;
}
if (event_child->must_set_ptrace_flags)
{
linux_enable_event_reporting (lwpid_of (event_child));
event_child->must_set_ptrace_flags = 0;
}
if (WIFSTOPPED (*wstat) && WSTOPSIG (*wstat) == SIGTRAP
&& *wstat >> 16 != 0)
{
handle_extended_wait (event_child, *wstat);
continue;
}
if (WIFSTOPPED (*wstat)
&& WSTOPSIG (*wstat) == SIGSTOP
&& event_child->stop_expected)
{
int should_stop;
if (debug_threads)
fprintf (stderr, "Expected stop.\n");
event_child->stop_expected = 0;
should_stop = (current_inferior->last_resume_kind == resume_stop
|| stopping_threads != NOT_STOPPING_THREADS);
if (!should_stop)
{
linux_resume_one_lwp (event_child,
event_child->stepping, 0, NULL);
continue;
}
}
return lwpid_of (event_child);
}
/* NOTREACHED */
return 0;
}
/* Count the LWP's that have had events. */
static int
count_events_callback (struct inferior_list_entry *entry, void *data)
{
struct lwp_info *lp = (struct lwp_info *) entry;
struct thread_info *thread = get_lwp_thread (lp);
int *count = data;
gdb_assert (count != NULL);
/* Count only resumed LWPs that have a SIGTRAP event pending that
should be reported to GDB. */
if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
&& thread->last_resume_kind != resume_stop
&& lp->status_pending_p
&& WIFSTOPPED (lp->status_pending)
&& WSTOPSIG (lp->status_pending) == SIGTRAP
&& !breakpoint_inserted_here (lp->stop_pc))
(*count)++;
return 0;
}
/* Select the LWP (if any) that is currently being single-stepped. */
static int
select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data)
{
struct lwp_info *lp = (struct lwp_info *) entry;
struct thread_info *thread = get_lwp_thread (lp);
if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
&& thread->last_resume_kind == resume_step
&& lp->status_pending_p)
return 1;
else
return 0;
}
/* Select the Nth LWP that has had a SIGTRAP event that should be
reported to GDB. */
static int
select_event_lwp_callback (struct inferior_list_entry *entry, void *data)
{
struct lwp_info *lp = (struct lwp_info *) entry;
struct thread_info *thread = get_lwp_thread (lp);
int *selector = data;
gdb_assert (selector != NULL);
/* Select only resumed LWPs that have a SIGTRAP event pending. */
if (thread->last_resume_kind != resume_stop
&& thread->last_status.kind == TARGET_WAITKIND_IGNORE
&& lp->status_pending_p
&& WIFSTOPPED (lp->status_pending)
&& WSTOPSIG (lp->status_pending) == SIGTRAP
&& !breakpoint_inserted_here (lp->stop_pc))
if ((*selector)-- == 0)
return 1;
return 0;
}
static int
cancel_breakpoints_callback (struct inferior_list_entry *entry, void *data)
{
struct lwp_info *lp = (struct lwp_info *) entry;
struct thread_info *thread = get_lwp_thread (lp);
struct lwp_info *event_lp = data;
/* Leave the LWP that has been elected to receive a SIGTRAP alone. */
if (lp == event_lp)
return 0;
/* 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 LWP will have already
tripped on it. */
if (thread->last_resume_kind != resume_stop
&& thread->last_status.kind == TARGET_WAITKIND_IGNORE
&& lp->status_pending_p
&& WIFSTOPPED (lp->status_pending)
&& WSTOPSIG (lp->status_pending) == SIGTRAP
&& !lp->stepping
&& !lp->stopped_by_watchpoint
&& cancel_breakpoint (lp))
/* Throw away the SIGTRAP. */
lp->status_pending_p = 0;
return 0;
}
static void
linux_cancel_breakpoints (void)
{
find_inferior (&all_lwps, cancel_breakpoints_callback, NULL);
}
/* Select one LWP out of those that have events pending. */
static void
select_event_lwp (struct lwp_info **orig_lp)
{
int num_events = 0;
int random_selector;
struct lwp_info *event_lp;
/* Give preference to any LWP that is being single-stepped. */
event_lp
= (struct lwp_info *) find_inferior (&all_lwps,
select_singlestep_lwp_callback, NULL);
if (event_lp != NULL)
{
if (debug_threads)
fprintf (stderr,
"SEL: Select single-step %s\n",
target_pid_to_str (ptid_of (event_lp)));
}
else
{
/* No single-stepping LWP. Select one at random, out of those
which have had SIGTRAP events. */
/* First see how many SIGTRAP events we have. */
find_inferior (&all_lwps, count_events_callback, &num_events);
/* Now randomly pick a LWP out of those that have had a SIGTRAP. */
random_selector = (int)
((num_events * (double) rand ()) / (RAND_MAX + 1.0));
if (debug_threads && num_events > 1)
fprintf (stderr,
"SEL: Found %d SIGTRAP events, selecting #%d\n",
num_events, random_selector);
event_lp = (struct lwp_info *) find_inferior (&all_lwps,
select_event_lwp_callback,
&random_selector);
}
if (event_lp != NULL)
{
/* Switch the event LWP. */
*orig_lp = event_lp;
}
}
/* Decrement the suspend count of an LWP. */
static int
unsuspend_one_lwp (struct inferior_list_entry *entry, void *except)
{
struct lwp_info *lwp = (struct lwp_info *) entry;
/* Ignore EXCEPT. */
if (lwp == except)
return 0;
lwp->suspended--;
gdb_assert (lwp->suspended >= 0);
return 0;
}
/* Decrement the suspend count of all LWPs, except EXCEPT, if non
NULL. */
static void
unsuspend_all_lwps (struct lwp_info *except)
{
find_inferior (&all_lwps, unsuspend_one_lwp, except);
}
static void move_out_of_jump_pad_callback (struct inferior_list_entry *entry);
static int stuck_in_jump_pad_callback (struct inferior_list_entry *entry,
void *data);
static int lwp_running (struct inferior_list_entry *entry, void *data);
static ptid_t linux_wait_1 (ptid_t ptid,
struct target_waitstatus *ourstatus,
int target_options);
/* Stabilize threads (move out of jump pads).
If a thread is midway collecting a fast tracepoint, we need to
finish the collection and move it out of the jump pad before
reporting the signal.
This avoids recursion while collecting (when a signal arrives
midway, and the signal handler itself collects), which would trash
the trace buffer. In case the user set a breakpoint in a signal
handler, this avoids the backtrace showing the jump pad, etc..
Most importantly, there are certain things we can't do safely if
threads are stopped in a jump pad (or in its callee's). For
example:
- starting a new trace run. A thread still collecting the
previous run, could trash the trace buffer when resumed. The trace
buffer control structures would have been reset but the thread had
no way to tell. The thread could even midway memcpy'ing to the
buffer, which would mean that when resumed, it would clobber the
trace buffer that had been set for a new run.
- we can't rewrite/reuse the jump pads for new tracepoints
safely. Say you do tstart while a thread is stopped midway while
collecting. When the thread is later resumed, it finishes the
collection, and returns to the jump pad, to execute the original
instruction that was under the tracepoint jump at the time the
older run had been started. If the jump pad had been rewritten
since for something else in the new run, the thread would now
execute the wrong / random instructions. */
static void
linux_stabilize_threads (void)
{
struct thread_info *save_inferior;
struct lwp_info *lwp_stuck;
lwp_stuck
= (struct lwp_info *) find_inferior (&all_lwps,
stuck_in_jump_pad_callback, NULL);
if (lwp_stuck != NULL)
{
if (debug_threads)
fprintf (stderr, "can't stabilize, LWP %ld is stuck in jump pad\n",
lwpid_of (lwp_stuck));
return;
}
save_inferior = current_inferior;
stabilizing_threads = 1;
/* Kick 'em all. */
for_each_inferior (&all_lwps, move_out_of_jump_pad_callback);
/* Loop until all are stopped out of the jump pads. */
while (find_inferior (&all_lwps, lwp_running, NULL) != NULL)
{
struct target_waitstatus ourstatus;
struct lwp_info *lwp;
int wstat;
/* Note that we go through the full wait even loop. While
moving threads out of jump pad, we need to be able to step
over internal breakpoints and such. */
linux_wait_1 (minus_one_ptid, &ourstatus, 0);
if (ourstatus.kind == TARGET_WAITKIND_STOPPED)
{
lwp = get_thread_lwp (current_inferior);
/* Lock it. */
lwp->suspended++;
if (ourstatus.value.sig != GDB_SIGNAL_0
|| current_inferior->last_resume_kind == resume_stop)
{
wstat = W_STOPCODE (gdb_signal_to_host (ourstatus.value.sig));
enqueue_one_deferred_signal (lwp, &wstat);
}
}
}
find_inferior (&all_lwps, unsuspend_one_lwp, NULL);
stabilizing_threads = 0;
current_inferior = save_inferior;
if (debug_threads)
{
lwp_stuck
= (struct lwp_info *) find_inferior (&all_lwps,
stuck_in_jump_pad_callback, NULL);
if (lwp_stuck != NULL)
fprintf (stderr, "couldn't stabilize, LWP %ld got stuck in jump pad\n",
lwpid_of (lwp_stuck));
}
}
/* Wait for process, returns status. */
static ptid_t
linux_wait_1 (ptid_t ptid,
struct target_waitstatus *ourstatus, int target_options)
{
int w;
struct lwp_info *event_child;
int options;
int pid;
int step_over_finished;
int bp_explains_trap;
int maybe_internal_trap;
int report_to_gdb;
int trace_event;
/* Translate generic target options into linux options. */
options = __WALL;
if (target_options & TARGET_WNOHANG)
options |= WNOHANG;
retry:
bp_explains_trap = 0;
trace_event = 0;
ourstatus->kind = TARGET_WAITKIND_IGNORE;
/* If we were only supposed to resume one thread, only wait for
that thread - if it's still alive. If it died, however - which
can happen if we're coming from the thread death case below -
then we need to make sure we restart the other threads. We could
pick a thread at random or restart all; restarting all is less
arbitrary. */
if (!non_stop
&& !ptid_equal (cont_thread, null_ptid)
&& !ptid_equal (cont_thread, minus_one_ptid))
{
struct thread_info *thread;
thread = (struct thread_info *) find_inferior_id (&all_threads,
cont_thread);
/* No stepping, no signal - unless one is pending already, of course. */
if (thread == NULL)
{
struct thread_resume resume_info;
resume_info.thread = minus_one_ptid;
resume_info.kind = resume_continue;
resume_info.sig = 0;
linux_resume (&resume_info, 1);
}
else
ptid = cont_thread;
}
if (ptid_equal (step_over_bkpt, null_ptid))
pid = linux_wait_for_event (ptid, &w, options);
else
{
if (debug_threads)
fprintf (stderr, "step_over_bkpt set [%s], doing a blocking wait\n",
target_pid_to_str (step_over_bkpt));
pid = linux_wait_for_event (step_over_bkpt, &w, options & ~WNOHANG);
}
if (pid == 0) /* only if TARGET_WNOHANG */
return null_ptid;
event_child = get_thread_lwp (current_inferior);
/* If we are waiting for a particular child, and it exited,
linux_wait_for_event will return its exit status. Similarly if
the last child exited. If this is not the last child, however,
do not report it as exited until there is a 'thread exited' response
available in the remote protocol. Instead, just wait for another event.
This should be safe, because if the thread crashed we will already
have reported the termination signal to GDB; that should stop any
in-progress stepping operations, etc.
Report the exit status of the last thread to exit. This matches
LinuxThreads' behavior. */
if (last_thread_of_process_p (current_inferior))
{
if (WIFEXITED (w) || WIFSIGNALED (w))
{
if (WIFEXITED (w))
{
ourstatus->kind = TARGET_WAITKIND_EXITED;
ourstatus->value.integer = WEXITSTATUS (w);
if (debug_threads)
fprintf (stderr,
"\nChild exited with retcode = %x \n",
WEXITSTATUS (w));
}
else
{
ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
if (debug_threads)
fprintf (stderr,
"\nChild terminated with signal = %x \n",
WTERMSIG (w));
}
return ptid_of (event_child);
}
}
else
{
if (!WIFSTOPPED (w))
goto retry;
}
/* If this event was not handled before, and is not a SIGTRAP, we
report it. SIGILL and SIGSEGV are also treated as traps in case
a breakpoint is inserted at the current PC. If this target does
not support internal breakpoints at all, we also report the
SIGTRAP without further processing; it's of no concern to us. */
maybe_internal_trap
= (supports_breakpoints ()
&& (WSTOPSIG (w) == SIGTRAP
|| ((WSTOPSIG (w) == SIGILL
|| WSTOPSIG (w) == SIGSEGV)
&& (*the_low_target.breakpoint_at) (event_child->stop_pc))));
if (maybe_internal_trap)
{
/* Handle anything that requires bookkeeping before deciding to
report the event or continue waiting. */
/* First check if we can explain the SIGTRAP with an internal
breakpoint, or if we should possibly report the event to GDB.
Do this before anything that may remove or insert a
breakpoint. */
bp_explains_trap = breakpoint_inserted_here (event_child->stop_pc);
/* We have a SIGTRAP, possibly a step-over dance has just
finished. If so, tweak the state machine accordingly,
reinsert breakpoints and delete any reinsert (software
single-step) breakpoints. */
step_over_finished = finish_step_over (event_child);
/* Now invoke the callbacks of any internal breakpoints there. */
check_breakpoints (event_child->stop_pc);
/* Handle tracepoint data collecting. This may overflow the
trace buffer, and cause a tracing stop, removing
breakpoints. */
trace_event = handle_tracepoints (event_child);
if (bp_explains_trap)
{
/* If we stepped or ran into an internal breakpoint, we've
already handled it. So next time we resume (from this
PC), we should step over it. */
if (debug_threads)
fprintf (stderr, "Hit a gdbserver breakpoint.\n");
if (breakpoint_here (event_child->stop_pc))
event_child->need_step_over = 1;
}
}
else
{
/* We have some other signal, possibly a step-over dance was in
progress, and it should be cancelled too. */
step_over_finished = finish_step_over (event_child);
}
/* We have all the data we need. Either report the event to GDB, or
resume threads and keep waiting for more. */
/* If we're collecting a fast tracepoint, finish the collection and
move out of the jump pad before delivering a signal. See
linux_stabilize_threads. */
if (WIFSTOPPED (w)
&& WSTOPSIG (w) != SIGTRAP
&& supports_fast_tracepoints ()
&& agent_loaded_p ())
{
if (debug_threads)
fprintf (stderr,
"Got signal %d for LWP %ld. Check if we need "
"to defer or adjust it.\n",
WSTOPSIG (w), lwpid_of (event_child));
/* Allow debugging the jump pad itself. */
if (current_inferior->last_resume_kind != resume_step
&& maybe_move_out_of_jump_pad (event_child, &w))
{
enqueue_one_deferred_signal (event_child, &w);
if (debug_threads)
fprintf (stderr,
"Signal %d for LWP %ld deferred (in jump pad)\n",
WSTOPSIG (w), lwpid_of (event_child));
linux_resume_one_lwp (event_child, 0, 0, NULL);
goto retry;
}
}
if (event_child->collecting_fast_tracepoint)
{
if (debug_threads)
fprintf (stderr, "\
LWP %ld was trying to move out of the jump pad (%d). \
Check if we're already there.\n",
lwpid_of (event_child),
event_child->collecting_fast_tracepoint);
trace_event = 1;
event_child->collecting_fast_tracepoint
= linux_fast_tracepoint_collecting (event_child, NULL);
if (event_child->collecting_fast_tracepoint != 1)
{
/* No longer need this breakpoint. */
if (event_child->exit_jump_pad_bkpt != NULL)
{
if (debug_threads)
fprintf (stderr,
"No longer need exit-jump-pad bkpt; removing it."
"stopping all threads momentarily.\n");
/* Other running threads could hit this breakpoint.
We don't handle moribund locations like GDB does,
instead we always pause all threads when removing
breakpoints, so that any step-over or
decr_pc_after_break adjustment is always taken
care of while the breakpoint is still
inserted. */
stop_all_lwps (1, event_child);
cancel_breakpoints ();
delete_breakpoint (event_child->exit_jump_pad_bkpt);
event_child->exit_jump_pad_bkpt = NULL;
unstop_all_lwps (1, event_child);
gdb_assert (event_child->suspended >= 0);
}
}
if (event_child->collecting_fast_tracepoint == 0)
{
if (debug_threads)
fprintf (stderr,
"fast tracepoint finished "
"collecting successfully.\n");
/* We may have a deferred signal to report. */
if (dequeue_one_deferred_signal (event_child, &w))
{
if (debug_threads)
fprintf (stderr, "dequeued one signal.\n");
}
else
{
if (debug_threads)
fprintf (stderr, "no deferred signals.\n");
if (stabilizing_threads)
{
ourstatus->kind = TARGET_WAITKIND_STOPPED;
ourstatus->value.sig = GDB_SIGNAL_0;
return ptid_of (event_child);
}
}
}
}
/* Check whether GDB would be interested in this event. */
/* If GDB is not interested in this signal, don't stop other
threads, and don't report it to GDB. Just resume the inferior
right away. We do this for threading-related signals as well as
any that GDB specifically requested we ignore. But never ignore
SIGSTOP if we sent it ourselves, and do not ignore signals when
stepping - they may require special handling to skip the signal
handler. */
/* FIXME drow/2002-06-09: Get signal numbers from the inferior's
thread library? */
if (WIFSTOPPED (w)
&& current_inferior->last_resume_kind != resume_step
&& (
#if defined (USE_THREAD_DB) && !defined (__ANDROID__)
(current_process ()->private->thread_db != NULL
&& (WSTOPSIG (w) == __SIGRTMIN
|| WSTOPSIG (w) == __SIGRTMIN + 1))
||
#endif
(pass_signals[gdb_signal_from_host (WSTOPSIG (w))]
&& !(WSTOPSIG (w) == SIGSTOP
&& current_inferior->last_resume_kind == resume_stop))))
{
siginfo_t info, *info_p;
if (debug_threads)
fprintf (stderr, "Ignored signal %d for LWP %ld.\n",
WSTOPSIG (w), lwpid_of (event_child));
if (ptrace (PTRACE_GETSIGINFO, lwpid_of (event_child), 0, &info) == 0)
info_p = &info;
else
info_p = NULL;
linux_resume_one_lwp (event_child, event_child->stepping,
WSTOPSIG (w), info_p);
goto retry;
}
/* If GDB wanted this thread to single step, we always want to
report the SIGTRAP, and let GDB handle it. Watchpoints should
always be reported. So should signals we can't explain. A
SIGTRAP we can't explain could be a GDB breakpoint --- we may or
not support Z0 breakpoints. If we do, we're be able to handle
GDB breakpoints on top of internal breakpoints, by handling the
internal breakpoint and still reporting the event to GDB. If we
don't, we're out of luck, GDB won't see the breakpoint hit. */
report_to_gdb = (!maybe_internal_trap
|| current_inferior->last_resume_kind == resume_step
|| event_child->stopped_by_watchpoint
|| (!step_over_finished
&& !bp_explains_trap && !trace_event)
|| (gdb_breakpoint_here (event_child->stop_pc)
&& gdb_condition_true_at_breakpoint (event_child->stop_pc)
&& gdb_no_commands_at_breakpoint (event_child->stop_pc)));
run_breakpoint_commands (event_child->stop_pc);
/* We found no reason GDB would want us to stop. We either hit one
of our own breakpoints, or finished an internal step GDB
shouldn't know about. */
if (!report_to_gdb)
{
if (debug_threads)
{
if (bp_explains_trap)
fprintf (stderr, "Hit a gdbserver breakpoint.\n");
if (step_over_finished)
fprintf (stderr, "Step-over finished.\n");
if (trace_event)
fprintf (stderr, "Tracepoint event.\n");
}
/* We're not reporting this breakpoint to GDB, so apply the
decr_pc_after_break adjustment to the inferior's regcache
ourselves. */
if (the_low_target.set_pc != NULL)
{
struct regcache *regcache
= get_thread_regcache (get_lwp_thread (event_child), 1);
(*the_low_target.set_pc) (regcache, event_child->stop_pc);
}
/* We may have finished stepping over a breakpoint. If so,
we've stopped and suspended all LWPs momentarily except the
stepping one. This is where we resume them all again. We're
going to keep waiting, so use proceed, which handles stepping
over the next breakpoint. */
if (debug_threads)
fprintf (stderr, "proceeding all threads.\n");
if (step_over_finished)
unsuspend_all_lwps (event_child);
proceed_all_lwps ();
goto retry;
}
if (debug_threads)
{
if (current_inferior->last_resume_kind == resume_step)
fprintf (stderr, "GDB wanted to single-step, reporting event.\n");
if (event_child->stopped_by_watchpoint)
fprintf (stderr, "Stopped by watchpoint.\n");
if (gdb_breakpoint_here (event_child->stop_pc))
fprintf (stderr, "Stopped by GDB breakpoint.\n");
if (debug_threads)
fprintf (stderr, "Hit a non-gdbserver trap event.\n");
}
/* Alright, we're going to report a stop. */
if (!non_stop && !stabilizing_threads)
{
/* In all-stop, stop all threads. */
stop_all_lwps (0, NULL);
/* If we're not waiting for a specific LWP, choose an event LWP
from among those that have had events. Giving equal priority
to all LWPs that have had events helps prevent
starvation. */
if (ptid_equal (ptid, minus_one_ptid))
{
event_child->status_pending_p = 1;
event_child->status_pending = w;
select_event_lwp (&event_child);
event_child->status_pending_p = 0;
w = event_child->status_pending;
}
/* Now that we've selected our final event LWP, cancel any
breakpoints in other LWPs that have hit a GDB breakpoint.
See the comment in cancel_breakpoints_callback to find out
why. */
find_inferior (&all_lwps, cancel_breakpoints_callback, event_child);
/* If we were going a step-over, all other threads but the stepping one
had been paused in start_step_over, with their suspend counts
incremented. We don't want to do a full unstop/unpause, because we're
in all-stop mode (so we want threads stopped), but we still need to
unsuspend the other threads, to decrement their `suspended' count
back. */
if (step_over_finished)
unsuspend_all_lwps (event_child);
/* Stabilize threads (move out of jump pads). */
stabilize_threads ();
}
else
{
/* If we just finished a step-over, then all threads had been
momentarily paused. In all-stop, that's fine, we want
threads stopped by now anyway. In non-stop, we need to
re-resume threads that GDB wanted to be running. */
if (step_over_finished)
unstop_all_lwps (1, event_child);
}
ourstatus->kind = TARGET_WAITKIND_STOPPED;
if (current_inferior->last_resume_kind == resume_stop
&& WSTOPSIG (w) == SIGSTOP)
{
/* A thread that has been requested to stop by GDB with vCont;t,
and it stopped cleanly, so report as SIG0. The use of
SIGSTOP is an implementation detail. */
ourstatus->value.sig = GDB_SIGNAL_0;
}
else if (current_inferior->last_resume_kind == resume_stop
&& WSTOPSIG (w) != SIGSTOP)
{
/* A thread that has been requested to stop by GDB with vCont;t,
but, it stopped for other reasons. */
ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
}
else
{
ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
}
gdb_assert (ptid_equal (step_over_bkpt, null_ptid));
if (debug_threads)
fprintf (stderr, "linux_wait ret = %s, %d, %d\n",
target_pid_to_str (ptid_of (event_child)),
ourstatus->kind,
ourstatus->value.sig);
return ptid_of (event_child);
}
/* Get rid of any pending event in the pipe. */
static void
async_file_flush (void)
{
int ret;
char buf;
do
ret = read (linux_event_pipe[0], &buf, 1);
while (ret >= 0 || (ret == -1 && errno == EINTR));
}
/* Put something in the pipe, so the event loop wakes up. */
static void
async_file_mark (void)
{
int ret;
async_file_flush ();
do
ret = write (linux_event_pipe[1], "+", 1);
while (ret == 0 || (ret == -1 && errno == EINTR));
/* Ignore EAGAIN. If the pipe is full, the event loop will already
be awakened anyway. */
}
static ptid_t
linux_wait (ptid_t ptid,
struct target_waitstatus *ourstatus, int target_options)
{
ptid_t event_ptid;
if (debug_threads)
fprintf (stderr, "linux_wait: [%s]\n", target_pid_to_str (ptid));
/* Flush the async file first. */
if (target_is_async_p ())
async_file_flush ();
event_ptid = linux_wait_1 (ptid, ourstatus, target_options);
/* If at least one stop was reported, there may be more. A single
SIGCHLD can signal more than one child stop. */
if (target_is_async_p ()
&& (target_options & TARGET_WNOHANG) != 0
&& !ptid_equal (event_ptid, null_ptid))
async_file_mark ();
return event_ptid;
}
/* Send a signal to an LWP. */
static int
kill_lwp (unsigned long lwpid, int signo)
{
/* Use tkill, if possible, in case we are using nptl threads. If tkill
fails, then we are not using nptl threads and we should be using kill. */
#ifdef __NR_tkill
{
static int tkill_failed;
if (!tkill_failed)
{
int ret;
errno = 0;
ret = syscall (__NR_tkill, lwpid, signo);
if (errno != ENOSYS)
return ret;
tkill_failed = 1;
}
}
#endif
return kill (lwpid, signo);
}
void
linux_stop_lwp (struct lwp_info *lwp)
{
send_sigstop (lwp);
}
static void
send_sigstop (struct lwp_info *lwp)
{
int pid;
pid = lwpid_of (lwp);
/* If we already have a pending stop signal for this process, don't
send another. */
if (lwp->stop_expected)
{
if (debug_threads)
fprintf (stderr, "Have pending sigstop for lwp %d\n", pid);
return;
}
if (debug_threads)
fprintf (stderr, "Sending sigstop to lwp %d\n", pid);
lwp->stop_expected = 1;
kill_lwp (pid, SIGSTOP);
}
static int
send_sigstop_callback (struct inferior_list_entry *entry, void *except)
{
struct lwp_info *lwp = (struct lwp_info *) entry;
/* Ignore EXCEPT. */
if (lwp == except)
return 0;
if (lwp->stopped)
return 0;
send_sigstop (lwp);
return 0;
}
/* Increment the suspend count of an LWP, and stop it, if not stopped
yet. */
static int
suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
void *except)
{
struct lwp_info *lwp = (struct lwp_info *) entry;
/* Ignore EXCEPT. */
if (lwp == except)
return 0;
lwp->suspended++;
return send_sigstop_callback (entry, except);
}
static void
mark_lwp_dead (struct lwp_info *lwp, int wstat)
{
/* It's dead, really. */
lwp->dead = 1;
/* Store the exit status for later. */
lwp->status_pending_p = 1;
lwp->status_pending = wstat;
/* Prevent trying to stop it. */
lwp->stopped = 1;
/* No further stops are expected from a dead lwp. */
lwp->stop_expected = 0;
}
static void
wait_for_sigstop (struct inferior_list_entry *entry)
{
struct lwp_info *lwp = (struct lwp_info *) entry;
struct thread_info *saved_inferior;
int wstat;
ptid_t saved_tid;
ptid_t ptid;
int pid;
if (lwp->stopped)
{
if (debug_threads)
fprintf (stderr, "wait_for_sigstop: LWP %ld already stopped\n",
lwpid_of (lwp));
return;
}
saved_inferior = current_inferior;
if (saved_inferior != NULL)
saved_tid = ((struct inferior_list_entry *) saved_inferior)->id;
else
saved_tid = null_ptid; /* avoid bogus unused warning */
ptid = lwp->head.id;
if (debug_threads)
fprintf (stderr, "wait_for_sigstop: pulling one event\n");
pid = linux_wait_for_event (ptid, &wstat, __WALL);
/* If we stopped with a non-SIGSTOP signal, save it for later
and record the pending SIGSTOP. If the process exited, just
return. */
if (WIFSTOPPED (wstat))
{
if (debug_threads)
fprintf (stderr, "LWP %ld stopped with signal %d\n",
lwpid_of (lwp), WSTOPSIG (wstat));
if (WSTOPSIG (wstat) != SIGSTOP)
{
if (debug_threads)
fprintf (stderr, "LWP %ld stopped with non-sigstop status %06x\n",
lwpid_of (lwp), wstat);
lwp->status_pending_p = 1;
lwp->status_pending = wstat;
}
}
else
{
if (debug_threads)
fprintf (stderr, "Process %d exited while stopping LWPs\n", pid);
lwp = find_lwp_pid (pid_to_ptid (pid));
if (lwp)