attach_state_redelivered_get (attach_state));
abort ();
}
- if (attach_state_threads_count_get (attach_state)
- == spawned_threads_count)
- break;
- fprintf (stderr, "FIXME: Untested threads initialization - REMOVE.\n");
/* During the inferior's initialization we may catch less threads. */
assert (attach_state_threads_count_get (attach_state)
- < spawned_threads_count);
+ <= spawned_threads_count);
+ if (attach_state_threads_count_get (attach_state)
+ == spawned_threads_count
+ /* Inferior may got stopped before it could initialize. */
+ || attach_state_stopped_get (attach_state) == 1)
+ {
+ /* FIXME: Why also STATE_STOPPED? */
+ STATE (pid, (1 << STATE_PTRACED) | (1 << STATE_STOPPED));
+ return attach_state;
+ }
/* WARNING: Currently we never use REDELIVERED_EXPECT but we would have to
probably reset it back to 0 otherwise. */
assert (redelivered_expect == 0);
detach_checked (attach_state);
}
while (loops++ < LOOPS_MIN || time (NULL) < timeout);
- assert (attach_state_threads_count_get (attach_state) == spawned_threads_count);
-
- /* FIXME: Why also STATE_STOPPED? */
- STATE (pid, (1 << STATE_PTRACED) | (1 << STATE_STOPPED));
- return attach_state;
+ abort ();
}
struct registry
static __attribute__((__noreturn__)) void child_alrm (void)
{
- void (*handler_orig) (int signo);
#if 0
int i;
sigset_t oldset;
#endif
- handler_orig = signal (SIGALRM, child_alrm_handler);
- assert (handler_orig == SIG_DFL);
+ /* Assumed already setup SIGALRM for CHILD_ALRM_HANDLER. */
#if 0
i = sigprocmask (SIG_BLOCK, NULL, &oldset);
pid_t inferior;
struct attach_state_struct *attach_state;
int i;
+ void (*handler_orig) (int signo);
assert (input == NULL);
murder (inferior);
/* Attach to a stopped process with already pending SIGALRM. */
+ /* Setup the handler already in the parent to avoid the child race. */
+ handler_orig = signal (SIGALRM, child_alrm_handler);
+ assert (handler_orig == SIG_DFL);
inferior = (unsigned long) (*child) (data, child_alrm);
+ handler_orig = signal (SIGALRM, handler_orig);
+ assert (handler_orig == child_alrm_handler);
STATE (inferior, 1 << STATE_SLEEPING);
delay ();
i = tkill (inferior, SIGSTOP);