* 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>
|
2006-09-21 Daniel Jacobowitz <dan@codesourcery.com>
|
||||||
|
|
||||||
* remote-utils.c (try_rle): New function.
|
* remote-utils.c (try_rle): New function.
|
||||||
|
|
|
@ -38,6 +38,11 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/syscall.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,
|
/* ``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
|
however. This requires changing the ID in place when we go from !using_threads
|
||||||
to using_threads, immediately.
|
to using_threads, immediately.
|
||||||
|
@ -54,7 +59,7 @@ int stopping_threads;
|
||||||
int using_threads;
|
int using_threads;
|
||||||
|
|
||||||
static void linux_resume_one_process (struct inferior_list_entry *entry,
|
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 linux_resume (struct thread_resume *resume_info);
|
||||||
static void stop_all_processes (void);
|
static void stop_all_processes (void);
|
||||||
static int linux_wait_for_event (struct thread_info *child);
|
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
|
struct pending_signals
|
||||||
{
|
{
|
||||||
int signal;
|
int signal;
|
||||||
|
siginfo_t info;
|
||||||
struct pending_signals *prev;
|
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
|
So instead of reporting the old SIGTRAP, pretend we got to
|
||||||
the breakpoint just after it was removed instead of just
|
the breakpoint just after it was removed instead of just
|
||||||
before; resume the process. */
|
before; resume the process. */
|
||||||
linux_resume_one_process (&process->head, 0, 0);
|
linux_resume_one_process (&process->head, 0, 0, NULL);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,6 +425,8 @@ linux_wait_for_process (struct process_info **childp, int *wstatp)
|
||||||
(*childp)->stopped = 1;
|
(*childp)->stopped = 1;
|
||||||
(*childp)->pending_is_breakpoint = 0;
|
(*childp)->pending_is_breakpoint = 0;
|
||||||
|
|
||||||
|
(*childp)->last_status = *wstatp;
|
||||||
|
|
||||||
if (debug_threads
|
if (debug_threads
|
||||||
&& WIFSTOPPED (*wstatp))
|
&& WIFSTOPPED (*wstatp))
|
||||||
{
|
{
|
||||||
|
@ -527,7 +535,7 @@ linux_wait_for_event (struct thread_info *child)
|
||||||
fprintf (stderr, "Expected stop.\n");
|
fprintf (stderr, "Expected stop.\n");
|
||||||
event_child->stop_expected = 0;
|
event_child->stop_expected = 0;
|
||||||
linux_resume_one_process (&event_child->head,
|
linux_resume_one_process (&event_child->head,
|
||||||
event_child->stepping, 0);
|
event_child->stepping, 0, NULL);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,13 +545,20 @@ linux_wait_for_event (struct thread_info *child)
|
||||||
&& (WSTOPSIG (wstat) == __SIGRTMIN
|
&& (WSTOPSIG (wstat) == __SIGRTMIN
|
||||||
|| WSTOPSIG (wstat) == __SIGRTMIN + 1))
|
|| WSTOPSIG (wstat) == __SIGRTMIN + 1))
|
||||||
{
|
{
|
||||||
|
siginfo_t info, *info_p;
|
||||||
|
|
||||||
if (debug_threads)
|
if (debug_threads)
|
||||||
fprintf (stderr, "Ignored signal %d for %ld (LWP %ld).\n",
|
fprintf (stderr, "Ignored signal %d for %ld (LWP %ld).\n",
|
||||||
WSTOPSIG (wstat), event_child->tid,
|
WSTOPSIG (wstat), event_child->tid,
|
||||||
event_child->head.id);
|
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,
|
linux_resume_one_process (&event_child->head,
|
||||||
event_child->stepping,
|
event_child->stepping,
|
||||||
WSTOPSIG (wstat));
|
WSTOPSIG (wstat), info_p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -572,7 +587,7 @@ linux_wait_for_event (struct thread_info *child)
|
||||||
event_child->bp_reinsert = 0;
|
event_child->bp_reinsert = 0;
|
||||||
|
|
||||||
/* Clear the single-stepping flag and SIGTRAP as we resume. */
|
/* 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,13 +624,13 @@ linux_wait_for_event (struct thread_info *child)
|
||||||
{
|
{
|
||||||
event_child->bp_reinsert = stop_pc;
|
event_child->bp_reinsert = stop_pc;
|
||||||
uninsert_breakpoint (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
|
else
|
||||||
{
|
{
|
||||||
reinsert_breakpoint_by_bp
|
reinsert_breakpoint_by_bp
|
||||||
(stop_pc, (*the_low_target.breakpoint_reinsert_addr) ());
|
(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;
|
continue;
|
||||||
|
@ -840,7 +855,7 @@ stop_all_processes (void)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
linux_resume_one_process (struct inferior_list_entry *entry,
|
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 process_info *process = (struct process_info *) entry;
|
||||||
struct thread_info *saved_inferior;
|
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 = malloc (sizeof (*p_sig));
|
||||||
p_sig->prev = process->pending_signals;
|
p_sig->prev = process->pending_signals;
|
||||||
p_sig->signal = signal;
|
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;
|
process->pending_signals = p_sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,6 +933,9 @@ linux_resume_one_process (struct inferior_list_entry *entry,
|
||||||
p_sig = &(*p_sig)->prev;
|
p_sig = &(*p_sig)->prev;
|
||||||
|
|
||||||
signal = (*p_sig)->signal;
|
signal = (*p_sig)->signal;
|
||||||
|
if ((*p_sig)->info.si_signo != 0)
|
||||||
|
ptrace (PTRACE_SETSIGINFO, process->lwpid, 0, &(*p_sig)->info);
|
||||||
|
|
||||||
free (*p_sig);
|
free (*p_sig);
|
||||||
*p_sig = NULL;
|
*p_sig = NULL;
|
||||||
}
|
}
|
||||||
|
@ -980,7 +1002,7 @@ linux_continue_one_thread (struct inferior_list_entry *entry)
|
||||||
else
|
else
|
||||||
step = process->resume->step;
|
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;
|
process->resume = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1011,6 +1033,16 @@ linux_queue_one_thread (struct inferior_list_entry *entry)
|
||||||
p_sig = malloc (sizeof (*p_sig));
|
p_sig = malloc (sizeof (*p_sig));
|
||||||
p_sig->prev = process->pending_signals;
|
p_sig->prev = process->pending_signals;
|
||||||
p_sig->signal = process->resume->sig;
|
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;
|
process->pending_signals = p_sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,9 @@ struct process_info
|
||||||
event already received in a wait()). */
|
event already received in a wait()). */
|
||||||
int stopped;
|
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
|
/* If this flag is set, we have sent a SIGSTOP to this process and are
|
||||||
waiting for it to stop. */
|
waiting for it to stop. */
|
||||||
int sigstop_sent;
|
int sigstop_sent;
|
||||||
|
|
Loading…
Reference in New Issue