@ -279,6 +279,10 @@ static struct lwp_info *find_lwp_pid (ptid_t ptid);
static int lwp_status_pending_p ( struct lwp_info * lp ) ;
static int check_stopped_by_breakpoint ( struct lwp_info * lp ) ;
static int sigtrap_is_event ( int status ) ;
static int ( * linux_nat_status_is_event ) ( int status ) = sigtrap_is_event ;
/* Trivial list manipulation functions to keep track of a list of
new stopped processes. */
@ -1519,12 +1523,25 @@ linux_resume_one_lwp (struct lwp_info *lp, int step, enum gdb_signal signo)
ptid_t ptid ;
lp - > step = step ;
/* stop_pc doubles as the PC the LWP had when it was last resumed.
We only presently need that if the LWP is stepped though (to
handle the case of stepping a breakpoint instruction). */
if ( step )
{
struct regcache * regcache = get_thread_regcache ( lp - > ptid ) ;
lp - > stop_pc = regcache_read_pc ( regcache ) ;
}
else
lp - > stop_pc = 0 ;
if ( linux_nat_prepare_to_resume ! = NULL )
linux_nat_prepare_to_resume ( lp ) ;
/* Convert to something the lower layer understands. */
ptid = pid_to_ptid ( ptid_get_lwp ( lp - > ptid ) ) ;
linux_ops - > to_resume ( linux_ops , ptid , step , signo ) ;
lp - > stopped_by_watchpoint = 0 ;
lp - > stop_reason = LWP_STOPPED_BY_NO_REASON ;
lp - > stopped = 0 ;
registers_changed_ptid ( lp - > ptid ) ;
}
@ -2374,24 +2391,21 @@ maybe_clear_ignore_sigint (struct lwp_info *lp)
soon as we see LP stop with a SIGTRAP. If GDB changes the debug
registers meanwhile, we have the cached data we can rely on. */
static void
save_sigtrap ( struct lwp_info * lp )
static int
check_stopped_by_watchpoint ( struct lwp_info * lp )
{
struct cleanup * old_chain ;
if ( linux_ops - > to_stopped_by_watchpoint = = NULL )
{
lp - > stopped_by_watchpoint = 0 ;
return ;
}
return 0 ;
old_chain = save_inferior_ptid ( ) ;
inferior_ptid = lp - > ptid ;
lp - > stopped_by_watchpoint = linux_ops - > to_stopped_by_watchpoint ( linux_ops ) ;
if ( lp - > stopped_by_watchpoint )
if ( linux_ops - > to_stopped_by_watchpoint ( linux_ops ) )
{
lp - > stop_reason = LWP_STOPPED_BY_WATCHPOINT ;
if ( linux_ops - > to_stopped_data_address ! = NULL )
lp - > stopped_data_address_p =
linux_ops - > to_stopped_data_address ( & current_target ,
@ -2401,9 +2415,27 @@ save_sigtrap (struct lwp_info *lp)
}
do_cleanups ( old_chain ) ;
return lp - > stop_reason = = LWP_STOPPED_BY_WATCHPOINT ;
}
/* See save_sigtrap. */
/* Called when the LWP stopped for a trap that could be explained by a
watchpoint or a breakpoint. */
static void
save_sigtrap ( struct lwp_info * lp )
{
gdb_assert ( lp - > stop_reason = = LWP_STOPPED_BY_NO_REASON ) ;
gdb_assert ( lp - > status ! = 0 ) ;
if ( check_stopped_by_watchpoint ( lp ) )
return ;
if ( linux_nat_status_is_event ( lp - > status ) )
check_stopped_by_breakpoint ( lp ) ;
}
/* Returns true if the LWP had stopped for a watchpoint. */
static int
linux_nat_stopped_by_watchpoint ( struct target_ops * ops )
@ -2412,7 +2444,7 @@ linux_nat_stopped_by_watchpoint (struct target_ops *ops)
gdb_assert ( lp ! = NULL ) ;
return lp - > stopped_by_watchpoint ;
return lp - > stop_reason = = LWP_STOPPED_BY_WATCHPOINT ;
}
static int
@ -2435,24 +2467,6 @@ sigtrap_is_event (int status)
return WIFSTOPPED ( status ) & & WSTOPSIG ( status ) = = SIGTRAP ;
}
/* SIGTRAP-like events recognizer. */
static int ( * linux_nat_status_is_event ) ( int status ) = sigtrap_is_event ;
/* Check for SIGTRAP-like events in LP. */
static int
linux_nat_lp_status_is_event ( struct lwp_info * lp )
{
/* We check for lp->waitstatus in addition to lp->status, because we can
have pending process exits recorded in lp->status
and W_EXITCODE(0,0) == 0. We should probably have an additional
lp->status_p flag. */
return ( lp - > waitstatus . kind = = TARGET_WAITKIND_IGNORE
& & linux_nat_status_is_event ( lp - > status ) ) ;
}
/* Set alternative SIGTRAP-like events recognizer. If
breakpoint_inserted_here_p there then gdbarch_decr_pc_after_break will be
applied. */
@ -2508,8 +2522,6 @@ stop_wait_callback (struct lwp_info *lp, void *data)
{
/* The thread was stopped with a signal other than SIGSTOP. */
save_sigtrap ( lp ) ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" SWC: Pending event %s in %s \n " ,
@ -2519,6 +2531,7 @@ stop_wait_callback (struct lwp_info *lp, void *data)
/* Save the sigtrap event. */
lp - > status = status ;
gdb_assert ( lp - > signalled ) ;
save_sigtrap ( lp ) ;
}
else
{
@ -2539,7 +2552,9 @@ stop_wait_callback (struct lwp_info *lp, void *data)
return 0 ;
}
/* Return non-zero if LP has a wait status pending. */
/* Return non-zero if LP has a wait status pending. Discard the
pending event and resume the LWP if the event that originally
caused the stop became uninteresting. */
static int
status_callback ( struct lwp_info * lp , void * data )
@ -2549,6 +2564,53 @@ status_callback (struct lwp_info *lp, void *data)
if ( ! lp - > resumed )
return 0 ;
if ( lp - > stop_reason = = LWP_STOPPED_BY_SW_BREAKPOINT
| | lp - > stop_reason = = LWP_STOPPED_BY_HW_BREAKPOINT )
{
struct regcache * regcache = get_thread_regcache ( lp - > ptid ) ;
struct gdbarch * gdbarch = get_regcache_arch ( regcache ) ;
CORE_ADDR pc ;
int discard = 0 ;
gdb_assert ( lp - > status ! = 0 ) ;
pc = regcache_read_pc ( regcache ) ;
if ( pc ! = lp - > stop_pc )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" SC: PC of %s changed. was=%s, now=%s \n " ,
target_pid_to_str ( lp - > ptid ) ,
paddress ( target_gdbarch ( ) , lp - > stop_pc ) ,
paddress ( target_gdbarch ( ) , pc ) ) ;
discard = 1 ;
}
else if ( ! breakpoint_inserted_here_p ( get_regcache_aspace ( regcache ) , pc ) )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" SC: previous breakpoint of %s, at %s gone \n " ,
target_pid_to_str ( lp - > ptid ) ,
paddress ( target_gdbarch ( ) , lp - > stop_pc ) ) ;
discard = 1 ;
}
if ( discard )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" SC: pending event of %s cancelled. \n " ,
target_pid_to_str ( lp - > ptid ) ) ;
lp - > status = 0 ;
linux_resume_one_lwp ( lp , lp - > step , GDB_SIGNAL_0 ) ;
return 0 ;
}
return 1 ;
}
return lwp_status_pending_p ( lp ) ;
}
@ -2570,8 +2632,8 @@ count_events_callback (struct lwp_info *lp, void *data)
gdb_assert ( count ! = NULL ) ;
/* Coun t only resumed LWPs that have a SIGTRAP event pending. */
if ( lp - > resumed & & linux_nat_lp_status_is_event ( lp ) )
/* Selec t only resumed LWPs that have an event pending. */
if ( lp - > resumed & & lwp_status_pending_p ( lp ) )
( * count ) + + ;
return 0 ;
@ -2609,16 +2671,19 @@ select_event_lwp_callback (struct lwp_info *lp, void *data)
gdb_assert ( selector ! = NULL ) ;
/* Select only resumed LWPs that have a SIGTRAP event pending. */
if ( lp - > resumed & & linux_nat_lp_status_is_event ( lp ) )
/* Select only resumed LWPs that have an event pending. */
if ( lp - > resumed & & lwp_status_pending_p ( lp ) )
if ( ( * selector ) - - = = 0 )
return 1 ;
return 0 ;
}
/* Called when the LWP got a signal/trap that could be explained by a
software or hardware breakpoint. */
static int
cancel _breakpoint ( struct lwp_info * lp )
check_stopped_by _breakpoint ( struct lwp_info * lp )
{
/* 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
@ -2632,48 +2697,42 @@ cancel_breakpoint (struct lwp_info *lp)
struct regcache * regcache = get_thread_regcache ( lp - > ptid ) ;
struct gdbarch * gdbarch = get_regcache_arch ( regcache ) ;
CORE_ADDR pc ;
CORE_ADDR sw_bp_pc ;
pc = regcache_read_pc ( regcache ) - target_decr_pc_after_break ( gdbarch ) ;
if ( breakpoint_inserted_here_p ( get_regcache_aspace ( regca che ) , pc ) )
pc = regcache_read_pc ( regcache ) ;
sw_bp_pc = pc - target_decr_pc_after_break ( gdbar ch) ;
if ( ( ! lp - > step | | lp - > stop_pc = = sw_bp_pc )
& & software_breakpoint_inserted_here_p ( get_regcache_aspace ( regcache ) ,
sw_bp_pc ) )
{
/* The LWP was either continued, or stepped a software
breakpoint instruction. */
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" CB: Push back breakpoint for %s \n " ,
" CB: Push back software breakpoint for %s \n " ,
target_pid_to_str ( lp - > ptid ) ) ;
/* Back up the PC if necessary. */
if ( target_decr_pc_after_break ( gdbarch ) )
regcache_write_pc ( regcache , pc ) ;
if ( pc ! = sw_bp_pc )
regcache_write_pc ( regcache , sw_bp_ pc) ;
lp - > stop_pc = sw_bp_pc ;
lp - > stop_reason = LWP_STOPPED_BY_SW_BREAKPOINT ;
return 1 ;
}
return 0 ;
}
static int
cancel_breakpoints_callback ( struct lwp_info * lp , void * data )
{
struct lwp_info * event_lp = data ;
if ( hardware_breakpoint_inserted_here_p ( get_regcache_aspace ( regcache ) , pc ) )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" CB: Push back hardware breakpoint for %s \n " ,
target_pid_to_str ( lp - > ptid ) ) ;
/* 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 ( linux_nat_lp_status_is_event ( lp )
& & cancel_breakpoint ( lp ) )
/* Throw away the SIGTRAP. */
lp - > status = 0 ;
lp - > stop_pc = pc ;
lp - > stop_reason = LWP_STOPPED_BY_HW_BREAKPOINT ;
return 1 ;
}
return 0 ;
}
@ -2685,36 +2744,48 @@ select_event_lwp (ptid_t filter, struct lwp_info **orig_lp, int *status)
{
int num_events = 0 ;
int random_selector ;
struct lwp_info * event_lp ;
struct lwp_info * event_lp = NULL ;
/* Record the wait status for the original LWP. */
( * orig_lp ) - > status = * status ;
/* G ive preference to any LWP that is being single-stepped. */
event_lp = iterate_over_lwps ( filter ,
select_singlestep_lwp_callback , NULL ) ;
if ( event_lp ! = NULL )
/* In all-stop, g ive preference to the LWP that is being
single-stepped. There will be at most one, and it will be the
LWP that the core is most interested in. If we didn't do this,
then we'd have to handle pending step SIGTRAPs somehow in case
the core later continues the previously-stepped thread, as
otherwise we'd report the pending SIGTRAP then, and the core, not
having stepped the thread, wouldn't understand what the trap was
for, and therefore would report it to the user as a random
signal. */
if ( ! non_stop )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" SEL: Select single-step %s \n " ,
target_pid_to_str ( event_lp - > ptid ) ) ;
event_lp = iterate_over_lwps ( filter ,
select_singlestep_lwp_callback , NULL ) ;
if ( event_lp ! = NULL )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" SEL: Select single-step %s \n " ,
target_pid_to_str ( event_lp - > ptid ) ) ;
}
}
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. */
if ( event_lp = = NULL )
{
/* Pick one at random, out of those which have had events. */
/* First see how many events we have. */
iterate_over_lwps ( filter , count_events_callback , & num_events ) ;
/* Now randomly pick a LWP out of those that have had a SIGTRAP. */
/* Now randomly pick a LWP out of those that have had
events. */
random_selector = ( int )
( ( num_events * ( double ) rand ( ) ) / ( RAND_MAX + 1.0 ) ) ;
if ( debug_linux_nat & & num_events > 1 )
fprintf_unfiltered ( gdb_stdlog ,
" SEL: Found %d SIGTRAP events, selecting #%d \n " ,
" SEL: Found %d events, selecting #%d \n " ,
num_events , random_selector ) ;
event_lp = iterate_over_lwps ( filter ,
@ -2748,8 +2819,6 @@ resumed_callback (struct lwp_info *lp, void *data)
static int
stop_and_resume_callback ( struct lwp_info * lp , void * data )
{
int * new_pending_p = data ;
if ( ! lp - > stopped )
{
ptid_t ptid = lp - > ptid ;
@ -2790,8 +2859,6 @@ stop_and_resume_callback (struct lwp_info *lp, void *data)
" SARC: not re-resuming LWP %ld "
" (has pending) \n " ,
ptid_get_lwp ( lp - > ptid ) ) ;
if ( new_pending_p )
* new_pending_p = 1 ;
}
}
}
@ -2799,18 +2866,14 @@ stop_and_resume_callback (struct lwp_info *lp, void *data)
}
/* Check if we should go on and pass this event to common code.
Return the affected lwp if we are, or NULL otherwise. If we stop
all lwps temporarily, we may end up with new pending events in some
other lwp. In that case set *NEW_PENDING_P to true. */
Return the affected lwp if we are, or NULL otherwise. */
static struct lwp_info *
linux_nat_filter_event ( int lwpid , int status , int * new_pending_p )
linux_nat_filter_event ( int lwpid , int status )
{
struct lwp_info * lp ;
int event = linux_ptrace_get_extended_event ( status ) ;
* new_pending_p = 0 ;
lp = find_lwp_pid ( pid_to_ptid ( lwpid ) ) ;
/* Check for stop events reported by a process we didn't already
@ -2890,42 +2953,62 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p)
return NULL ;
}
if ( linux_nat_status_is_event ( status ) )
save_sigtrap ( lp ) ;
/* Check if the thread has exited. */
if ( ( WIFEXITED ( status ) | | WIFSIGNALED ( status ) )
& & num_lwps ( ptid_get_pid ( lp - > ptid ) ) > 1 )
if ( WIFEXITED ( status ) | | WIFSIGNALED ( status ) )
{
/* If this is the main thread, we must stop all threads and verify
if they are still alive. This is because in the nptl thread model
on Linux 2.4, there is no signal issued for exiting LWPs
other than the main thread. We only get the main thread exit
signal once all child threads have already exited. If we
stop all the threads and use the stop_wait_callback to check
if they have exited we can determine whether this signal
should be ignored or whether it means the end of the debugged
application, regardless of which threading model is being
used. */
if ( ptid_get_pid ( lp - > ptid ) = = ptid_get_lwp ( lp - > ptid ) )
if ( num_lwps ( ptid_get_pid ( lp - > ptid ) ) > 1 )
{
iterate_over_lwps ( pid_to_ptid ( ptid_get_pid ( lp - > ptid ) ) ,
stop_and_resume_callback , new_pending_p ) ;
/* If this is the main thread, we must stop all threads and
verify if they are still alive. This is because in the
nptl thread model on Linux 2.4, there is no signal issued
for exiting LWPs other than the main thread. We only get
the main thread exit signal once all child threads have
already exited. If we stop all the threads and use the
stop_wait_callback to check if they have exited we can
determine whether this signal should be ignored or
whether it means the end of the debugged application,
regardless of which threading model is being used. */
if ( ptid_get_pid ( lp - > ptid ) = = ptid_get_lwp ( lp - > ptid ) )
{
iterate_over_lwps ( pid_to_ptid ( ptid_get_pid ( lp - > ptid ) ) ,
stop_and_resume_callback , NULL ) ;
}
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" LLW: %s exited. \n " ,
target_pid_to_str ( lp - > ptid ) ) ;
if ( num_lwps ( ptid_get_pid ( lp - > ptid ) ) > 1 )
{
/* If there is at least one more LWP, then the exit signal
was not the end of the debugged application and should be
ignored. */
exit_lwp ( lp ) ;
return NULL ;
}
}
gdb_assert ( lp - > resumed ) ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" LLW: %s exited. \n " ,
target_pid_to_str ( lp - > ptid ) ) ;
" Process %ld exited\n " ,
ptid_get_lwp ( lp - > ptid ) ) ;
if ( num_lwps ( ptid_get_pid ( lp - > ptid ) ) > 1 )
{
/* If there is at least one more LWP, then the exit signal
was not the end of the debugged application and should be
ignored . */
exit_lwp ( lp ) ;
return NULL ;
}
/* This was the last lwp in the process. Since events are
serialized to GDB core, we may not be able report this one
right now, but GDB core and the o ther target layers will want
to be notified about the exit code/signal, leave the status
pending for the next time we're able to report it . */
/* Dead LWP's aren't expected to reported a pending sigstop. */
lp - > signalled = 0 ;
/* Store the pending event in the waitstatus, because
W_EXITCODE(0,0) == 0. */
store_waitstatus ( & lp - > waitstatus , status ) ;
return lp ;
}
/* Check if the current LWP has previously exited. In the nptl
@ -3007,9 +3090,59 @@ linux_nat_filter_event (int lwpid, int status, int *new_pending_p)
return NULL ;
}
/* Don't report signals that GDB isn't interested in, such as
signals that are neither printed nor stopped upon. Stopping all
threads can be a bit time-consuming so if we want decent
performance with heavily multi-threaded programs, especially when
they're using a high frequency timer, we'd better avoid it if we
can. */
if ( WIFSTOPPED ( status ) )
{
enum gdb_signal signo = gdb_signal_from_host ( WSTOPSIG ( status ) ) ;
if ( ! non_stop )
{
/* Only do the below in all-stop, as we currently use SIGSTOP
to implement target_stop (see linux_nat_stop) in
non-stop. */
if ( signo = = GDB_SIGNAL_INT & & signal_pass_state ( signo ) = = 0 )
{
/* If ^C/BREAK is typed at the tty/console, SIGINT gets
forwarded to the entire process group, that is, all LWPs
will receive it - unless they're using CLONE_THREAD to
share signals. Since we only want to report it once, we
mark it as ignored for all LWPs except this one. */
iterate_over_lwps ( pid_to_ptid ( ptid_get_pid ( lp - > ptid ) ) ,
set_ignore_sigint , NULL ) ;
lp - > ignore_sigint = 0 ;
}
else
maybe_clear_ignore_sigint ( lp ) ;
}
/* When using hardware single-step, we need to report every signal.
Otherwise, signals in pass_mask may be short-circuited. */
if ( ! lp - > step
& & WSTOPSIG ( status ) & & sigismember ( & pass_mask , WSTOPSIG ( status ) ) )
{
linux_resume_one_lwp ( lp , lp - > step , signo ) ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" LLW: %s %s, %s (preempt 'handle') \n " ,
lp - > step ?
" PTRACE_SINGLESTEP " : " PTRACE_CONT " ,
target_pid_to_str ( lp - > ptid ) ,
( signo ! = GDB_SIGNAL_0
? strsignal ( gdb_signal_to_host ( signo ) )
: " 0 " ) ) ;
return NULL ;
}
}
/* An interesting event. */
gdb_assert ( lp ) ;
lp - > status = status ;
save_sigtrap ( lp ) ;
return lp ;
}
@ -3108,9 +3241,6 @@ linux_nat_wait_1 (struct target_ops *ops,
/* Make sure SIGCHLD is blocked until the sigsuspend below. */
block_child_signals ( & prev_mask ) ;
retry :
status = 0 ;
/* First check if there is a LWP with a wait status pending. */
lp = iterate_over_lwps ( ptid , status_callback , NULL ) ;
if ( lp ! = NULL )
@ -3128,7 +3258,9 @@ retry:
set_sigint_trap ( ) ;
}
/* But if we don't find a pending event, we'll have to wait. */
/* But if we don't find a pending event, we'll have to wait. Always
pull all events out of the kernel. We'll randomly select an
event LWP out of all that have events, to prevent starvation. */
while ( lp = = NULL )
{
@ -3159,10 +3291,6 @@ retry:
if ( lwpid > 0 )
{
/* If this is true, then we paused LWPs momentarily, and may
now have pending events to handle. */
int new_pending ;
if ( debug_linux_nat )
{
fprintf_unfiltered ( gdb_stdlog ,
@ -3170,101 +3298,18 @@ retry:
( long ) lwpid , status_to_str ( status ) ) ;
}
lp = linux_nat_filter_event ( lwpid , status , & new_pending );
/* STATUS is now no longer valid, use LP->STATUS instead. */
status = 0 ;
if ( lp & & ! ptid_match ( lp - > ptid , ptid ) )
{
gdb_assert ( lp - > resumed ) ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" LWP %ld got an event %06x, "
" leaving pending. \n " ,
ptid_get_lwp ( lp - > ptid ) , lp - > status ) ;
if ( WIFSTOPPED ( lp - > status ) )
{
if ( WSTOPSIG ( lp - > status ) ! = SIGSTOP )
{
/* Cancel breakpoint hits. The breakpoint may
be removed before we fetch events from this
process to report to the core. It is best
not to assume the moribund breakpoints
heuristic always handles these cases --- it
could be too many events go through to the
core before this one is handled. All-stop
always cancels breakpoint hits in all
threads. */
if ( non_stop
& & linux_nat_lp_status_is_event ( lp )
& & cancel_breakpoint ( lp ) )
{
/* Throw away the SIGTRAP. */
lp - > status = 0 ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" LLW: LWP %ld hit a "
" breakpoint while "
" waiting for another "
" process; "
" cancelled it \n " ,
ptid_get_lwp ( lp - > ptid ) ) ;
}
}
else
lp - > signalled = 0 ;
}
else if ( WIFEXITED ( lp - > status ) | | WIFSIGNALED ( lp - > status ) )
{
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" Process %ld exited while stopping "
" LWPs \n " ,
ptid_get_lwp ( lp - > ptid ) ) ;
/* This was the last lwp in the process. Since
events are serialized to GDB core, and we can't
report this one right now, but GDB core and the
other target layers will want to be notified
about the exit code/signal, leave the status
pending for the next time we're able to report
it. */
/* Dead LWP's aren't expected to reported a pending
sigstop. */
lp - > signalled = 0 ;
/* Store the pending event in the waitstatus as
well, because W_EXITCODE(0,0) == 0. */
store_waitstatus ( & lp - > waitstatus , lp - > status ) ;
}
/* Keep looking. */
lp = NULL ;
}
if ( new_pending )
{
/* Some LWP now has a pending event. Go all the way
back to check it. */
goto retry ;
}
if ( lp )
{
/* We got an event to report to the core. */
break ;
}
linux_nat_filter_event ( lwpid , status ) ;
/* Retry until nothing comes out of waitpid. A single
SIGCHLD can indicate more than one child stopped. */
continue ;
}
/* Now that we've pulled all events out of the kernel, check if
there's any LWP with a status to report to the core. */
lp = iterate_over_lwps ( ptid , status_callback , NULL ) ;
if ( lp ! = NULL )
break ;
/* Check for zombie thread group leaders. Those can't be reaped
until all other threads in the thread group are. */
check_zombie_leaders ( ) ;
@ -3314,68 +3359,6 @@ retry:
status = lp - > status ;
lp - > status = 0 ;
/* Don't report signals that GDB isn't interested in, such as
signals that are neither printed nor stopped upon. Stopping all
threads can be a bit time-consuming so if we want decent
performance with heavily multi-threaded programs, especially when
they're using a high frequency timer, we'd better avoid it if we
can. */
if ( WIFSTOPPED ( status ) )
{
enum gdb_signal signo = gdb_signal_from_host ( WSTOPSIG ( status ) ) ;
/* When using hardware single-step, we need to report every signal.
Otherwise, signals in pass_mask may be short-circuited. */
if ( ! lp - > step
& & WSTOPSIG ( status ) & & sigismember ( & pass_mask , WSTOPSIG ( status ) ) )
{
/* FIMXE: kettenis/2001-06-06: Should we resume all threads
here? It is not clear we should. GDB may not expect
other threads to run. On the other hand, not resuming
newly attached threads may cause an unwanted delay in
getting them running. */
linux_resume_one_lwp ( lp , lp - > step , signo ) ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog ,
" LLW: %s %s, %s (preempt 'handle') \n " ,
lp - > step ?
" PTRACE_SINGLESTEP " : " PTRACE_CONT " ,
target_pid_to_str ( lp - > ptid ) ,
( signo ! = GDB_SIGNAL_0
? strsignal ( gdb_signal_to_host ( signo ) )
: " 0 " ) ) ;
goto retry ;
}
if ( ! non_stop )
{
/* Only do the below in all-stop, as we currently use SIGINT
to implement target_stop (see linux_nat_stop) in
non-stop. */
if ( signo = = GDB_SIGNAL_INT & & signal_pass_state ( signo ) = = 0 )
{
/* If ^C/BREAK is typed at the tty/console, SIGINT gets
forwarded to the entire process group, that is, all LWPs
will receive it - unless they're using CLONE_THREAD to
share signals. Since we only want to report it once, we
mark it as ignored for all LWPs except this one. */
iterate_over_lwps ( pid_to_ptid ( ptid_get_pid ( ptid ) ) ,
set_ignore_sigint , NULL ) ;
lp - > ignore_sigint = 0 ;
}
else
maybe_clear_ignore_sigint ( lp ) ;
}
}
/* This LWP is stopped now. */
lp - > stopped = 1 ;
if ( debug_linux_nat )
fprintf_unfiltered ( gdb_stdlog , " LLW: Candidate event %s in %s. \n " ,
status_to_str ( status ) , target_pid_to_str ( lp - > ptid ) ) ;
if ( ! non_stop )
{
/* Now stop all other LWP's ... */
@ -3384,33 +3367,46 @@ retry:
/* ... and wait until all of them have reported back that
they're no longer running. */
iterate_over_lwps ( minus_one_ptid , stop_wait_callback , NULL ) ;
}
/* 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 ) | | ptid_is_pid ( ptid ) )
select_event_lwp ( ptid , & lp , & status ) ;
/* 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 ) | | ptid_is_pid ( ptid ) )
select_event_lwp ( ptid , & lp , & status ) ;
/* 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. */
iterate_over_lwps ( minus_one_ptid , cancel_breakpoints_callback , lp ) ;
gdb_assert ( lp ! = NULL ) ;
/* We'll need this to determine whether to report a SIGSTOP as
TARGET_WAITKIND_0. Need to take a copy because
resume_clear_callback clears it. */
last_resume_kind = lp - > last_resume_kind ;
/* Now that we've selected our final event LWP, un-adjust its PC if
it was a software breakpoint. */
if ( lp - > stop_reason = = LWP_STOPPED_BY_SW_BREAKPOINT )
{
struct regcache * regcache = get_thread_regcache ( lp - > ptid ) ;
struct gdbarch * gdbarch = get_regcache_arch ( regcache ) ;
int decr_pc = target_decr_pc_after_break ( gdbarch ) ;
if ( decr_pc ! = 0 )
{
CORE_ADDR pc ;
pc = regcache_read_pc ( regcache ) ;
regcache_write_pc ( regcache , pc + decr_pc ) ;
}
}
/* We'll need this to determine whether to report a SIGSTOP as
GDB_SIGNAL_0. Need to take a copy because resume_clear_callback
clears it. */
last_resume_kind = lp - > last_resume_kind ;
if ( ! non_stop )
{
/* In all-stop, from the core's perspective, all LWPs are now
stopped until a new resume action is sent over. */
iterate_over_lwps ( minus_one_ptid , resume_clear_callback , NULL ) ;
}
else
{
/* See above. */
last_resume_kind = lp - > last_resume_kind ;
resume_clear_callback ( lp , NULL ) ;
}