Fix race during process detach

Summary:
The code which was preventing the usage of the OS plugin while detach is in
progress also prevented us to update the thread list correctly. This resulted
in an empty thread list, which confused the detaching logic. Change the
condition do only do what it says (disable the usage of the OS plugin).

Reviewers: clayborg, jingham

Subscribers: lldb-commits

Differential Revision: http://reviews.llvm.org/D14201

llvm-svn: 251932
This commit is contained in:
Pavel Labath 2015-11-03 16:05:18 +00:00
parent 53f8a53fb6
commit 862432c90e
2 changed files with 26 additions and 30 deletions

View File

@ -20,7 +20,6 @@ class AttachResumeTestCase(TestBase):
@skipIfRemote @skipIfRemote
@expectedFailureFreeBSD('llvm.org/pr19310') @expectedFailureFreeBSD('llvm.org/pr19310')
@expectedFailureWindows("llvm.org/pr24778") @expectedFailureWindows("llvm.org/pr24778")
@expectedFlakeyLinux('llvm.org/pr19310')
def test_attach_continue_interrupt_detach(self): def test_attach_continue_interrupt_detach(self):
"""Test attach/continue/interrupt/detach""" """Test attach/continue/interrupt/detach"""
self.build() self.build()

View File

@ -1565,41 +1565,38 @@ Process::UpdateThreadListIfNeeded ()
// Don't call into the OperatingSystem to update the thread list if we are shutting down, since // Don't call into the OperatingSystem to update the thread list if we are shutting down, since
// that may call back into the SBAPI's, requiring the API lock which is already held by whoever is // that may call back into the SBAPI's, requiring the API lock which is already held by whoever is
// shutting us down, causing a deadlock. // shutting us down, causing a deadlock.
if (!m_destroy_in_process) OperatingSystem *os = GetOperatingSystem ();
if (os && !m_destroy_in_process)
{ {
OperatingSystem *os = GetOperatingSystem (); // Clear any old backing threads where memory threads might have been
if (os) // backed by actual threads from the lldb_private::Process subclass
{ size_t num_old_threads = old_thread_list.GetSize(false);
// Clear any old backing threads where memory threads might have been for (size_t i=0; i<num_old_threads; ++i)
// backed by actual threads from the lldb_private::Process subclass old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
size_t num_old_threads = old_thread_list.GetSize(false);
for (size_t i=0; i<num_old_threads; ++i)
old_thread_list.GetThreadAtIndex(i, false)->ClearBackingThread();
// Turn off dynamic types to ensure we don't run any expressions. Objective C // Turn off dynamic types to ensure we don't run any expressions. Objective C
// can run an expression to determine if a SBValue is a dynamic type or not // can run an expression to determine if a SBValue is a dynamic type or not
// and we need to avoid this. OperatingSystem plug-ins can't run expressions // and we need to avoid this. OperatingSystem plug-ins can't run expressions
// that require running code... // that require running code...
Target &target = GetTarget(); Target &target = GetTarget();
const lldb::DynamicValueType saved_prefer_dynamic = target.GetPreferDynamicValue (); const lldb::DynamicValueType saved_prefer_dynamic = target.GetPreferDynamicValue ();
if (saved_prefer_dynamic != lldb::eNoDynamicValues) if (saved_prefer_dynamic != lldb::eNoDynamicValues)
target.SetPreferDynamicValue(lldb::eNoDynamicValues); target.SetPreferDynamicValue(lldb::eNoDynamicValues);
// Now let the OperatingSystem plug-in update the thread list // Now let the OperatingSystem plug-in update the thread list
os->UpdateThreadList (old_thread_list, // Old list full of threads created by OS plug-in os->UpdateThreadList (old_thread_list, // Old list full of threads created by OS plug-in
real_thread_list, // The actual thread list full of threads created by each lldb_private::Process subclass real_thread_list, // The actual thread list full of threads created by each lldb_private::Process subclass
new_thread_list); // The new thread list that we will show to the user that gets filled in new_thread_list); // The new thread list that we will show to the user that gets filled in
if (saved_prefer_dynamic != lldb::eNoDynamicValues) if (saved_prefer_dynamic != lldb::eNoDynamicValues)
target.SetPreferDynamicValue(saved_prefer_dynamic); target.SetPreferDynamicValue(saved_prefer_dynamic);
} }
else else
{ {
// No OS plug-in, the new thread list is the same as the real thread list // No OS plug-in, the new thread list is the same as the real thread list
new_thread_list = real_thread_list; new_thread_list = real_thread_list;
}
} }
m_thread_list_real.Update(real_thread_list); m_thread_list_real.Update(real_thread_list);