Author: jdevlieghere Date: Thu Apr 12 02:58:20 2018 New Revision: 329891 URL: http://llvm.org/viewvc/llvm-project?rev=329891&view=rev Log: Don't assume backing thread shares protocol ID.
When we're dealing with virtual (memory) threads created by the OS plugins, there's no guarantee that the real thread and the backing thread share a protocol ID. Instead, we should iterate over the memory threads to find the virtual thread that is backed by the current real thread. Differential revision: https://reviews.llvm.org/D45497 rdar://36485830 Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestThreadSelectionBug.py lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/operating_system.py Modified: lldb/trunk/include/lldb/Target/ThreadList.h lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/source/Target/ThreadList.cpp Modified: lldb/trunk/include/lldb/Target/ThreadList.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/ThreadList.h?rev=329891&r1=329890&r2=329891&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/ThreadList.h (original) +++ lldb/trunk/include/lldb/Target/ThreadList.h Thu Apr 12 02:58:20 2018 @@ -102,6 +102,8 @@ public: lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr); + lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread); + bool ShouldStop(Event *event_ptr); Vote ShouldReportStop(Event *event_ptr); Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestThreadSelectionBug.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestThreadSelectionBug.py?rev=329891&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestThreadSelectionBug.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestThreadSelectionBug.py Thu Apr 12 02:58:20 2018 @@ -0,0 +1,50 @@ +from __future__ import print_function +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +from gdbclientutils import * + + +class TestThreadSelectionBug(GDBRemoteTestBase): + def test(self): + class MyResponder(MockGDBServerResponder): + def cont(self): + # Simulate process stopping due to a raise(SIGINT) + return "T01reason:signal" + + self.server.responder = MyResponder() + target = self.createTarget("a.yaml") + process = self.connect(target) + python_os_plugin_path = os.path.join(self.getSourceDir(), + 'operating_system.py') + command = "settings set target.process.python-os-plugin-path '{}'".format( + python_os_plugin_path) + self.dbg.HandleCommand(command) + + self.assertTrue(process, PROCESS_IS_VALID) + self.assertEqual(process.GetNumThreads(), 3) + + # Verify our OS plug-in threads showed up + thread = process.GetThreadByID(0x1) + self.assertTrue( + thread.IsValid(), + "Make sure there is a thread 0x1 after we load the python OS plug-in") + thread = process.GetThreadByID(0x2) + self.assertTrue( + thread.IsValid(), + "Make sure there is a thread 0x2 after we load the python OS plug-in") + thread = process.GetThreadByID(0x3) + self.assertTrue( + thread.IsValid(), + "Make sure there is a thread 0x3 after we load the python OS plug-in") + + # Verify that a thread other than 3 is selected. + thread = process.GetSelectedThread() + self.assertNotEqual(thread.GetThreadID(), 0x3) + + # Verify that we select the thread backed by physical thread 1, rather + # than virtual thread 1. The mapping comes from the OS plugin, where we + # specified that thread 3 is backed by real thread 1. + process.Continue() + thread = process.GetSelectedThread() + self.assertEqual(thread.GetThreadID(), 0x3) Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/operating_system.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/operating_system.py?rev=329891&view=auto ============================================================================== --- lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/operating_system.py (added) +++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/operating_system.py Thu Apr 12 02:58:20 2018 @@ -0,0 +1,45 @@ +import lldb +import struct + + +class OperatingSystemPlugIn(object): + """Class that provides data for an instance of a LLDB 'OperatingSystemPython' plug-in class""" + + def __init__(self, process): + '''Initialization needs a valid.SBProcess object. + + This plug-in will get created after a live process is valid and has stopped for the first time. + ''' + self.process = None + self.registers = None + self.threads = None + if isinstance(process, lldb.SBProcess) and process.IsValid(): + self.process = process + self.threads = None # Will be an dictionary containing info for each thread + + def get_target(self): + return self.process.target + + def get_thread_info(self): + if not self.threads: + self.threads = [{ + 'tid': 0x1, + 'name': 'one', + 'queue': 'queue1', + 'state': 'stopped', + 'stop_reason': 'none' + }, { + 'tid': 0x2, + 'name': 'two', + 'queue': 'queue2', + 'state': 'stopped', + 'stop_reason': 'none' + }, { + 'tid': 0x3, + 'name': 'three', + 'queue': 'queue3', + 'state': 'stopped', + 'stop_reason': 'sigstop', + 'core': 0 + }] + return self.threads Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=329891&r1=329890&r2=329891&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Thu Apr 12 02:58:20 2018 @@ -1822,10 +1822,9 @@ ThreadSP ProcessGDBRemote::SetThreadStop if (!thread_sp->StopInfoIsUpToDate()) { thread_sp->SetStopInfo(StopInfoSP()); // If there's a memory thread backed by this thread, we need to use it - // to calcualte StopInfo. - ThreadSP memory_thread_sp = - m_thread_list.FindThreadByProtocolID(thread_sp->GetProtocolID()); - if (memory_thread_sp) + // to calculate StopInfo. + if (ThreadSP memory_thread_sp = + m_thread_list.GetBackingThread(thread_sp)) thread_sp = memory_thread_sp; if (exc_type != 0) { Modified: lldb/trunk/source/Target/ThreadList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/ThreadList.cpp?rev=329891&r1=329890&r2=329891&view=diff ============================================================================== --- lldb/trunk/source/Target/ThreadList.cpp (original) +++ lldb/trunk/source/Target/ThreadList.cpp Thu Apr 12 02:58:20 2018 @@ -195,6 +195,20 @@ ThreadSP ThreadList::GetThreadSPForThrea return thread_sp; } +ThreadSP ThreadList::GetBackingThread(const ThreadSP &real_thread) { + std::lock_guard<std::recursive_mutex> guard(GetMutex()); + + ThreadSP thread_sp; + const uint32_t num_threads = m_threads.size(); + for (uint32_t idx = 0; idx < num_threads; ++idx) { + if (m_threads[idx]->GetBackingThread() == real_thread) { + thread_sp = m_threads[idx]; + break; + } + } + return thread_sp; +} + ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) { std::lock_guard<std::recursive_mutex> guard(GetMutex()); _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits