* linux-low.c (PTRACE_GETSIGINFO, PTRACE_SETSIGINFO): Define.
(linux_resume_one_process): Take a siginfo_t *. Update all callers. Queue it if necessary. Use PTRACE_SETSIGINFO. (struct pending_signals): Add a siginfo_t. (linux_wait_for_process): Always set last_status. (linux_wait_for_event): Use PTRACE_GETSIGINFO. (linux_queue_one_thread): Use PTRACE_GETSIGINFO. * linux-low.h (struct process_info): Add last_status.
This commit is contained in:
parent
ef05d49568
commit
32ca6d6157
|
@ -1,3 +1,14 @@
|
|||
2006-09-28 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* linux-low.c (PTRACE_GETSIGINFO, PTRACE_SETSIGINFO): Define.
|
||||
(linux_resume_one_process): Take a siginfo_t *. Update all
|
||||
callers. Queue it if necessary. Use PTRACE_SETSIGINFO.
|
||||
(struct pending_signals): Add a siginfo_t.
|
||||
(linux_wait_for_process): Always set last_status.
|
||||
(linux_wait_for_event): Use PTRACE_GETSIGINFO.
|
||||
(linux_queue_one_thread): Use PTRACE_GETSIGINFO.
|
||||
* linux-low.h (struct process_info): Add last_status.
|
||||
|
||||
2006-09-21 Daniel Jacobowitz <dan@codesourcery.com>
|
||||
|
||||
* remote-utils.c (try_rle): New function.
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#ifndef PTRACE_GETSIGINFO
|
||||
# define PTRACE_GETSIGINFO 0x4202
|
||||
# define PTRACE_SETSIGINFO 0x4203
|
||||
#endif
|
||||
|
||||
/* ``all_threads'' is keyed by the LWP ID - it should be the thread ID instead,
|
||||
however. This requires changing the ID in place when we go from !using_threads
|
||||
to using_threads, immediately.
|
||||
|
@ -54,7 +59,7 @@ int stopping_threads;
|
|||
int using_threads;
|
||||
|
||||
static void linux_resume_one_process (struct inferior_list_entry *entry,
|
||||
int step, int signal);
|
||||
int step, int signal, siginfo_t *info);
|
||||
static void linux_resume (struct thread_resume *resume_info);
|
||||
static void stop_all_processes (void);
|
||||
static int linux_wait_for_event (struct thread_info *child);
|
||||
|
@ -62,6 +67,7 @@ static int linux_wait_for_event (struct thread_info *child);
|
|||
struct pending_signals
|
||||
{
|
||||
int signal;
|
||||
siginfo_t info;
|
||||
struct pending_signals *prev;
|
||||
};
|
||||
|
||||
|
@ -366,7 +372,7 @@ status_pending_p (struct inferior_list_entry *entry, void *dummy)
|
|||
So instead of reporting the old SIGTRAP, pretend we got to
|
||||
the breakpoint just after it was removed instead of just
|
||||
before; resume the process. */
|
||||
linux_resume_one_process (&process->head, 0, 0);
|
||||
linux_resume_one_process (&process->head, 0, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -419,6 +425,8 @@ linux_wait_for_process (struct process_info **childp, int *wstatp)
|
|||
(*childp)->stopped = 1;
|
||||
(*childp)->pending_is_breakpoint = 0;
|
||||
|
||||
(*childp)->last_status = *wstatp;
|
||||
|
||||
if (debug_threads
|
||||
&& WIFSTOPPED (*wstatp))
|
||||
{
|
||||
|
@ -527,7 +535,7 @@ linux_wait_for_event (struct thread_info *child)
|
|||
fprintf (stderr, "Expected stop.\n");
|
||||
event_child->stop_expected = 0;
|
||||
linux_resume_one_process (&event_child->head,
|
||||
event_child->stepping, 0);
|
||||
event_child->stepping, 0, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -537,13 +545,20 @@ linux_wait_for_event (struct thread_info *child)
|
|||
&& (WSTOPSIG (wstat) == __SIGRTMIN
|
||||
|| WSTOPSIG (wstat) == __SIGRTMIN + 1))
|
||||
{
|
||||
siginfo_t info, *info_p;
|
||||
|
||||
if (debug_threads)
|
||||
fprintf (stderr, "Ignored signal %d for %ld (LWP %ld).\n",
|
||||
WSTOPSIG (wstat), event_child->tid,
|
||||
event_child->head.id);
|
||||
|
||||
if (ptrace (PTRACE_GETSIGINFO, event_child->lwpid, 0, &info) == 0)
|
||||
info_p = &info;
|
||||
else
|
||||
info_p = NULL;
|
||||
linux_resume_one_process (&event_child->head,
|
||||
event_child->stepping,
|
||||
WSTOPSIG (wstat));
|
||||
WSTOPSIG (wstat), info_p);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -572,7 +587,7 @@ linux_wait_for_event (struct thread_info *child)
|
|||
event_child->bp_reinsert = 0;
|
||||
|
||||
/* Clear the single-stepping flag and SIGTRAP as we resume. */
|
||||
linux_resume_one_process (&event_child->head, 0, 0);
|
||||
linux_resume_one_process (&event_child->head, 0, 0, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -609,13 +624,13 @@ linux_wait_for_event (struct thread_info *child)
|
|||
{
|
||||
event_child->bp_reinsert = stop_pc;
|
||||
uninsert_breakpoint (stop_pc);
|
||||
linux_resume_one_process (&event_child->head, 1, 0);
|
||||
linux_resume_one_process (&event_child->head, 1, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
reinsert_breakpoint_by_bp
|
||||
(stop_pc, (*the_low_target.breakpoint_reinsert_addr) ());
|
||||
linux_resume_one_process (&event_child->head, 0, 0);
|
||||
linux_resume_one_process (&event_child->head, 0, 0, NULL);
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -840,7 +855,7 @@ stop_all_processes (void)
|
|||
|
||||
static void
|
||||
linux_resume_one_process (struct inferior_list_entry *entry,
|
||||
int step, int signal)
|
||||
int step, int signal, siginfo_t *info)
|
||||
{
|
||||
struct process_info *process = (struct process_info *) entry;
|
||||
struct thread_info *saved_inferior;
|
||||
|
@ -859,6 +874,10 @@ linux_resume_one_process (struct inferior_list_entry *entry,
|
|||
p_sig = malloc (sizeof (*p_sig));
|
||||
p_sig->prev = process->pending_signals;
|
||||
p_sig->signal = signal;
|
||||
if (info == NULL)
|
||||
memset (&p_sig->info, 0, sizeof (siginfo_t));
|
||||
else
|
||||
memcpy (&p_sig->info, info, sizeof (siginfo_t));
|
||||
process->pending_signals = p_sig;
|
||||
}
|
||||
|
||||
|
@ -914,6 +933,9 @@ linux_resume_one_process (struct inferior_list_entry *entry,
|
|||
p_sig = &(*p_sig)->prev;
|
||||
|
||||
signal = (*p_sig)->signal;
|
||||
if ((*p_sig)->info.si_signo != 0)
|
||||
ptrace (PTRACE_SETSIGINFO, process->lwpid, 0, &(*p_sig)->info);
|
||||
|
||||
free (*p_sig);
|
||||
*p_sig = NULL;
|
||||
}
|
||||
|
@ -980,7 +1002,7 @@ linux_continue_one_thread (struct inferior_list_entry *entry)
|
|||
else
|
||||
step = process->resume->step;
|
||||
|
||||
linux_resume_one_process (&process->head, step, process->resume->sig);
|
||||
linux_resume_one_process (&process->head, step, process->resume->sig, NULL);
|
||||
|
||||
process->resume = NULL;
|
||||
}
|
||||
|
@ -1011,6 +1033,16 @@ linux_queue_one_thread (struct inferior_list_entry *entry)
|
|||
p_sig = malloc (sizeof (*p_sig));
|
||||
p_sig->prev = process->pending_signals;
|
||||
p_sig->signal = process->resume->sig;
|
||||
memset (&p_sig->info, 0, sizeof (siginfo_t));
|
||||
|
||||
/* If this is the same signal we were previously stopped by,
|
||||
make sure to queue its siginfo. We can ignore the return
|
||||
value of ptrace; if it fails, we'll skip
|
||||
PTRACE_SETSIGINFO. */
|
||||
if (WIFSTOPPED (process->last_status)
|
||||
&& WSTOPSIG (process->last_status) == process->resume->sig)
|
||||
ptrace (PTRACE_GETSIGINFO, process->lwpid, 0, &p_sig->info);
|
||||
|
||||
process->pending_signals = p_sig;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,9 @@ struct process_info
|
|||
event already received in a wait()). */
|
||||
int stopped;
|
||||
|
||||
/* When stopped is set, the last wait status recorded for this process. */
|
||||
int last_status;
|
||||
|
||||
/* If this flag is set, we have sent a SIGSTOP to this process and are
|
||||
waiting for it to stop. */
|
||||
int sigstop_sent;
|
||||
|
|
Loading…
Reference in New Issue