Index: source/Plugins/Process/Linux/NativeProcessLinux.cpp =================================================================== --- source/Plugins/Process/Linux/NativeProcessLinux.cpp +++ source/Plugins/Process/Linux/NativeProcessLinux.cpp @@ -2261,24 +2261,67 @@ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)): { // This is the notification on the parent thread which informs us of new thread - // creation. We are not interested in these events at this point (an interesting use - // case would be to stop the process upon thread creation), so we just resume the thread. - // We will pickup the new thread when we get its SIGSTOP notification. + // creation. + // We don't want to do anything with the parent thread so we just resume it. In case we + // want to implement "break on thread creation" functionality, we would need to stop + // here. + Resume (pid, LLDB_INVALID_SIGNAL_NUMBER); - if (log) + unsigned long event_message = 0; + if (GetEventMessage (pid, &event_message).Fail()) { - unsigned long event_message = 0; - if (GetEventMessage (pid, &event_message).Success()) - { - lldb::tid_t tid = static_cast (event_message); - log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event for tid %" PRIu64, __FUNCTION__, pid, tid); - - } - else + if (log) log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event but GetEventMessage failed so we don't know the new tid", __FUNCTION__, pid); + break; } - Resume (pid, LLDB_INVALID_SIGNAL_NUMBER); + ::pid_t tid = static_cast<::pid_t> (event_message); + NativeThreadProtocolSP new_thread_sp = GetThreadByID(tid); + + if (new_thread_sp) + { + // We are already tracking the thread - we got the event on the new thread (see + // MonitorSignal) before this one. We are done. + break; + } + + // The thread is not tracked yet, let's wait for it to appear. + int status = -1; + ::pid_t wait_pid; + do + { + if (log) + log->Printf ("NativeProcessLinux::%s() pid %" PRIu64 " received thread creation event for tid %" PRIu32 ". tid not tracked yet, waiting for thread to appear...", __FUNCTION__, pid, tid); + wait_pid = waitpid(pid, &status, __WALL); + } + while (wait_pid == -1 && errno == EINTR); + // Since we are waiting on a specific tid, this must be the creation event. But let's do + // some checks just in case. + if (wait_pid != tid) { + if (log) + log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " failed. Assuming the thread has disappeared in the meantime", __FUNCTION__, tid); + // The only way I know of this could happen is if the whole process was + // SIGKILLed in the mean time. In any case, we can't do anything about that now. + break; + } + if (WIFEXITED(status)) + { + if (log) + log->Printf ("NativeProcessLinux::%s() waiting for tid %" PRIu32 " returned an 'exited' event. Not tracking the thread.", __FUNCTION__, tid); + // Also a very improbable event. + break; + } + // In theory we should now continue and do a PTRACE_GETSIGINFO and verify that this is + // really a thread creation event. However, in practice, there isn't much we could do + // about it even if it wasn't - the thread tid does exist and we are receiving events + // from it, so we might as well start tracking it. + if (log) + log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 ": tracking new thread tid %" PRIu32, + __FUNCTION__, GetID (), tid); + new_thread_sp = AddThread(tid); + std::static_pointer_cast (new_thread_sp)->SetRunning (); + Resume (tid, LLDB_INVALID_SIGNAL_NUMBER); + m_coordinator_up->NotifyThreadCreate (tid, false, CoordinatorErrorHandler); break; } @@ -2597,8 +2640,10 @@ // Check for new thread notification. if ((info->si_pid == 0) && (info->si_code == SI_USER)) { - // A new thread creation is being signaled. This is one of two parts that come in - // a non-deterministic order. pid is the thread id. + // A new thread creation is being signaled. This is one of two parts that come in + // a non-deterministic order. This code handles the case where the new thread event comes + // before the event on the parent thread. For the opposite case see code in + // MonitorSIGTRAP. if (log) log->Printf ("NativeProcessLinux::%s() pid = %" PRIu64 " tid %" PRIu64 ": new thread notification", __FUNCTION__, GetID (), pid);