@@ -426,22 +426,24 @@ Status NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
426
426
}
427
427
428
428
// Handles all waitpid events from the inferior process.
429
- void NativeProcessLinux::MonitorCallback (lldb::pid_t pid, WaitStatus status) {
429
+ void NativeProcessLinux::MonitorCallback (NativeThreadLinux &thread,
430
+ WaitStatus status) {
430
431
Log *log (GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS));
431
432
432
433
// Certain activities differ based on whether the pid is the tid of the main
433
434
// thread.
434
- const bool is_main_thread = (pid == GetID ());
435
+ const bool is_main_thread = (thread. GetID () == GetID ());
435
436
436
437
// Handle when the thread exits.
437
438
if (status.type == WaitStatus::Exit || status.type == WaitStatus::Signal) {
438
439
LLDB_LOG (log,
439
440
" got exit status({0}) , tid = {1} ({2} main thread), process "
440
441
" state = {3}" ,
441
- status, pid, is_main_thread ? " is" : " is not" , GetState ());
442
+ status, thread.GetID (), is_main_thread ? " is" : " is not" ,
443
+ GetState ());
442
444
443
445
// This is a thread that exited. Ensure we're not tracking it anymore.
444
- StopTrackingThread (pid );
446
+ StopTrackingThread (thread );
445
447
446
448
if (is_main_thread) {
447
449
// The main thread exited. We're done monitoring. Report to delegate.
@@ -454,37 +456,15 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, WaitStatus status) {
454
456
}
455
457
456
458
siginfo_t info;
457
- const auto info_err = GetSignalInfo (pid, &info);
458
- auto thread_sp = GetThreadByID (pid);
459
-
460
- if (!thread_sp) {
461
- // Normally, the only situation when we cannot find the thread is if we
462
- // have just received a new thread notification. This is indicated by
463
- // GetSignalInfo() returning si_code == SI_USER and si_pid == 0
464
- LLDB_LOG (log, " received notification about an unknown tid {0}." , pid);
465
-
466
- if (info_err.Fail ()) {
467
- LLDB_LOG (log,
468
- " (tid {0}) GetSignalInfo failed ({1}). "
469
- " Ingoring this notification." ,
470
- pid, info_err);
471
- return ;
472
- }
473
-
474
- LLDB_LOG (log, " tid {0}, si_code: {1}, si_pid: {2}" , pid, info.si_code ,
475
- info.si_pid );
476
-
477
- MonitorClone (pid, llvm::None);
478
- return ;
479
- }
459
+ const auto info_err = GetSignalInfo (thread.GetID (), &info);
480
460
481
461
// Get details on the signal raised.
482
462
if (info_err.Success ()) {
483
463
// We have retrieved the signal info. Dispatch appropriately.
484
464
if (info.si_signo == SIGTRAP)
485
- MonitorSIGTRAP (info, *thread_sp );
465
+ MonitorSIGTRAP (info, thread );
486
466
else
487
- MonitorSignal (info, *thread_sp );
467
+ MonitorSignal (info, thread );
488
468
} else {
489
469
if (info_err.GetError () == EINVAL) {
490
470
// This is a group stop reception for this tid. We can reach here if we
@@ -500,9 +480,8 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, WaitStatus status) {
500
480
" received a group stop for pid {0} tid {1}. Transparent "
501
481
" handling of group stops not supported, resuming the "
502
482
" thread." ,
503
- GetID (), pid);
504
- ResumeThread (*thread_sp, thread_sp->GetState (),
505
- LLDB_INVALID_SIGNAL_NUMBER);
483
+ GetID (), thread.GetID ());
484
+ ResumeThread (thread, thread.GetState (), LLDB_INVALID_SIGNAL_NUMBER);
506
485
} else {
507
486
// ptrace(GETSIGINFO) failed (but not due to group-stop).
508
487
@@ -512,12 +491,12 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, WaitStatus status) {
512
491
513
492
// Stop tracking the metadata for the thread since it's entirely off the
514
493
// system now.
515
- const bool thread_found = StopTrackingThread (pid );
494
+ StopTrackingThread (thread );
516
495
517
496
LLDB_LOG (log,
518
497
" GetSignalInfo failed: {0}, tid = {1}, status = {2}, "
519
- " status = {3}, main_thread = {4}, thread_found: {5} " ,
520
- info_err, pid , status, status, is_main_thread, thread_found );
498
+ " status = {3}, main_thread = {4}" ,
499
+ info_err, thread. GetID () , status, status, is_main_thread);
521
500
522
501
if (is_main_thread) {
523
502
// Notify the delegate - our process is not available but appears to
@@ -532,7 +511,7 @@ void NativeProcessLinux::MonitorCallback(lldb::pid_t pid, WaitStatus status) {
532
511
" pid {0} tid {1} non-main thread exit occurred, didn't "
533
512
" tell delegate anything since thread disappeared out "
534
513
" from underneath us" ,
535
- GetID (), pid );
514
+ GetID (), thread. GetID () );
536
515
}
537
516
}
538
517
}
@@ -549,29 +528,14 @@ void NativeProcessLinux::WaitForCloneNotification(::pid_t pid) {
549
528
pid);
550
529
::pid_t wait_pid =
551
530
llvm::sys::RetryAfterSignal (-1 , ::waitpid, pid, &status, __WALL);
552
- // Since we are waiting on a specific pid, this must be the creation event.
553
- // But let's do some checks just in case.
554
- if (wait_pid != pid) {
555
- LLDB_LOG (log,
556
- " waiting for pid {0} failed. Assuming the pid has "
557
- " disappeared in the meantime" ,
558
- pid);
559
- // The only way I know of this could happen is if the whole process was
560
- // SIGKILLed in the mean time. In any case, we can't do anything about that
561
- // now.
562
- return ;
563
- }
564
- if (WIFEXITED (status)) {
565
- LLDB_LOG (log,
566
- " waiting for pid {0} returned an 'exited' event. Not "
567
- " tracking it." ,
568
- pid);
569
- // Also a very improbable event.
570
- m_pending_pid_map.erase (pid);
571
- return ;
572
- }
573
531
574
- MonitorClone (pid, llvm::None);
532
+ // It's theoretically possible to get other events if the entire process was
533
+ // SIGKILLed before we got a chance to check this. In that case, we'll just
534
+ // clean everything up when we get the process exit event.
535
+
536
+ LLDB_LOG (log,
537
+ " waitpid({0}, &status, __WALL) => {1} (errno: {2}, status = {3})" ,
538
+ pid, wait_pid, errno, WaitStatus::Decode (status));
575
539
}
576
540
577
541
void NativeProcessLinux::MonitorSIGTRAP (const siginfo_t &info,
@@ -598,8 +562,7 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
598
562
thread.GetID ());
599
563
ResumeThread (thread, thread.GetState (), LLDB_INVALID_SIGNAL_NUMBER);
600
564
} else {
601
- if (!MonitorClone (event_message, {{(info.si_code >> 8 ), thread.GetID ()}}))
602
- WaitForCloneNotification (event_message);
565
+ MonitorClone (thread, event_message, info.si_code >> 8 );
603
566
}
604
567
605
568
break ;
@@ -886,36 +849,15 @@ void NativeProcessLinux::MonitorSignal(const siginfo_t &info,
886
849
StopRunningThreads (thread.GetID ());
887
850
}
888
851
889
- bool NativeProcessLinux::MonitorClone (
890
- lldb::pid_t child_pid,
891
- llvm::Optional<NativeProcessLinux::CloneInfo> clone_info) {
852
+ bool NativeProcessLinux::MonitorClone (NativeThreadLinux &parent,
853
+ lldb::pid_t child_pid, int event) {
892
854
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
893
- LLDB_LOG (log, " clone , child_pid={0 }, clone info?={1 }" , child_pid ,
894
- clone_info. hasValue () );
855
+ LLDB_LOG (log, " parent_tid={0} , child_pid={1 }, event={2 }" , parent. GetID () ,
856
+ child_pid, event );
895
857
896
- auto find_it = m_pending_pid_map.find (child_pid);
897
- if (find_it == m_pending_pid_map.end ()) {
898
- // not in the map, so this is the first signal for the PID
899
- m_pending_pid_map.insert ({child_pid, clone_info});
900
- return false ;
901
- }
902
- m_pending_pid_map.erase (find_it);
903
-
904
- // second signal for the pid
905
- assert (clone_info.hasValue () != find_it->second .hasValue ());
906
- if (!clone_info) {
907
- // child signal does not indicate the event, so grab the one stored
908
- // earlier
909
- clone_info = find_it->second ;
910
- }
911
-
912
- LLDB_LOG (log, " second signal for child_pid={0}, parent_tid={1}, event={2}" ,
913
- child_pid, clone_info->parent_tid , clone_info->event );
858
+ WaitForCloneNotification (child_pid);
914
859
915
- auto *parent_thread = GetThreadByID (clone_info->parent_tid );
916
- assert (parent_thread);
917
-
918
- switch (clone_info->event ) {
860
+ switch (event) {
919
861
case PTRACE_EVENT_CLONE: {
920
862
// PTRACE_EVENT_CLONE can either mean a new thread or a new process.
921
863
// Try to grab the new process' PGID to figure out which one it is.
@@ -930,15 +872,14 @@ bool NativeProcessLinux::MonitorClone(
930
872
ThreadWasCreated (child_thread);
931
873
932
874
// Resume the parent.
933
- ResumeThread (*parent_thread, parent_thread->GetState (),
934
- LLDB_INVALID_SIGNAL_NUMBER);
875
+ ResumeThread (parent, parent.GetState (), LLDB_INVALID_SIGNAL_NUMBER);
935
876
break ;
936
877
}
937
878
}
938
879
LLVM_FALLTHROUGH;
939
880
case PTRACE_EVENT_FORK:
940
881
case PTRACE_EVENT_VFORK: {
941
- bool is_vfork = clone_info-> event == PTRACE_EVENT_VFORK;
882
+ bool is_vfork = event == PTRACE_EVENT_VFORK;
942
883
std::unique_ptr<NativeProcessLinux> child_process{new NativeProcessLinux (
943
884
static_cast <::pid_t >(child_pid), m_terminal_fd, m_delegate, m_arch,
944
885
m_main_loop, {static_cast <::pid_t >(child_pid)})};
@@ -949,12 +890,11 @@ bool NativeProcessLinux::MonitorClone(
949
890
if (bool (m_enabled_extensions & expected_ext)) {
950
891
m_delegate.NewSubprocess (this , std::move (child_process));
951
892
// NB: non-vfork clone() is reported as fork
952
- parent_thread-> SetStoppedByFork (is_vfork, child_pid);
953
- StopRunningThreads (parent_thread-> GetID ());
893
+ parent. SetStoppedByFork (is_vfork, child_pid);
894
+ StopRunningThreads (parent. GetID ());
954
895
} else {
955
896
child_process->Detach ();
956
- ResumeThread (*parent_thread, parent_thread->GetState (),
957
- LLDB_INVALID_SIGNAL_NUMBER);
897
+ ResumeThread (parent, parent.GetState (), LLDB_INVALID_SIGNAL_NUMBER);
958
898
}
959
899
break ;
960
900
}
@@ -1729,24 +1669,19 @@ bool NativeProcessLinux::HasThreadNoLock(lldb::tid_t thread_id) {
1729
1669
return false ;
1730
1670
}
1731
1671
1732
- bool NativeProcessLinux::StopTrackingThread (lldb:: tid_t thread_id ) {
1672
+ void NativeProcessLinux::StopTrackingThread (NativeThreadLinux &thread ) {
1733
1673
Log *const log = ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD);
1734
- LLDB_LOG (log, " tid: {0})" , thread_id);
1735
-
1736
- bool found = false ;
1737
- for (auto it = m_threads.begin (); it != m_threads.end (); ++it) {
1738
- if (*it && ((*it)->GetID () == thread_id)) {
1739
- m_threads.erase (it);
1740
- found = true ;
1741
- break ;
1742
- }
1743
- }
1674
+ lldb::tid_t thread_id = thread.GetID ();
1675
+ LLDB_LOG (log, " tid: {0}" , thread_id);
1744
1676
1745
- if (found)
1746
- NotifyTracersOfThreadDestroyed (thread_id);
1677
+ auto it = llvm::find_if (m_threads, [&](const auto &thread_up) {
1678
+ return thread_up.get () == &thread;
1679
+ });
1680
+ assert (it != m_threads.end ());
1681
+ m_threads.erase (it);
1747
1682
1683
+ NotifyTracersOfThreadDestroyed (thread_id);
1748
1684
SignalIfAllThreadsStopped ();
1749
- return found;
1750
1685
}
1751
1686
1752
1687
Status NativeProcessLinux::NotifyTracersOfNewThread (lldb::tid_t tid) {
@@ -1945,27 +1880,44 @@ void NativeProcessLinux::ThreadWasCreated(NativeThreadLinux &thread) {
1945
1880
1946
1881
void NativeProcessLinux::SigchldHandler () {
1947
1882
Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
1948
- // Process all pending waitpid notifications.
1949
- while (true ) {
1883
+
1884
+ // Threads can appear or disappear as a result of event processing, so gather
1885
+ // the events upfront.
1886
+ llvm::DenseMap<lldb::tid_t , WaitStatus> tid_events;
1887
+ for (const auto &thread_up : m_threads) {
1950
1888
int status = -1 ;
1951
- ::pid_t wait_pid = llvm::sys::RetryAfterSignal (-1 , ::waitpid, -1 , &status,
1952
- __WALL | __WNOTHREAD | WNOHANG);
1889
+ ::pid_t wait_pid =
1890
+ llvm::sys::RetryAfterSignal (-1 , ::waitpid, thread_up->GetID (), &status,
1891
+ __WALL | __WNOTHREAD | WNOHANG);
1953
1892
1954
1893
if (wait_pid == 0 )
1955
- break ; // We are done .
1894
+ continue ; // Nothing to do for this thread .
1956
1895
1957
1896
if (wait_pid == -1 ) {
1958
1897
Status error (errno, eErrorTypePOSIX);
1959
- LLDB_LOG (log, " waitpid (-1, &status, _) failed: {0}" , error);
1960
- break ;
1898
+ LLDB_LOG (log, " waitpid({0}, &status, _) failed: {1}" , thread_up->GetID (),
1899
+ error);
1900
+ continue ;
1961
1901
}
1962
1902
1903
+ assert (wait_pid == static_cast <::pid_t >(thread_up->GetID ()));
1904
+
1963
1905
WaitStatus wait_status = WaitStatus::Decode (status);
1964
1906
1965
- LLDB_LOG (log, " waitpid (-1, &status, _) => pid = {0}, status = {1}" ,
1966
- wait_pid, wait_status);
1907
+ LLDB_LOG (log, " waitpid({0}) got status = {1}" , thread_up->GetID (),
1908
+ wait_status);
1909
+ tid_events.try_emplace (thread_up->GetID (), wait_status);
1910
+ }
1967
1911
1968
- MonitorCallback (wait_pid, wait_status);
1912
+ for (auto &KV : tid_events) {
1913
+ LLDB_LOG (log, " processing {0}({1}) ..." , KV.first , KV.second );
1914
+ NativeThreadLinux *thread = GetThreadByID (KV.first );
1915
+ if (thread) {
1916
+ MonitorCallback (*thread, KV.second );
1917
+ } else {
1918
+ // This can happen if one of the events is an main thread exit.
1919
+ LLDB_LOG (log, " ... but the thread has disappeared" );
1920
+ }
1969
1921
}
1970
1922
}
1971
1923
0 commit comments