[Lldb-commits] [lldb] r330005 - Re-land "Don't assume backing thread shares protocol ID."

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Fri Apr 13 04:31:34 PDT 2018


Author: jdevlieghere
Date: Fri Apr 13 04:31:34 2018
New Revision: 330005

URL: http://llvm.org/viewvc/llvm-project?rev=330005&view=rev
Log:
Re-land "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

The original revision (r329891) was reverted because the associated
tests ran into a deadlock on the Linux bots. That problem was resolved
by r330002.

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=330005&r1=330004&r2=330005&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Target/ThreadList.h (original)
+++ lldb/trunk/include/lldb/Target/ThreadList.h Fri Apr 13 04:31:34 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=330005&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 Fri Apr 13 04:31:34 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=330005&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 Fri Apr 13 04:31:34 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=330005&r1=330004&r2=330005&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Fri Apr 13 04:31:34 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=330005&r1=330004&r2=330005&view=diff
==============================================================================
--- lldb/trunk/source/Target/ThreadList.cpp (original)
+++ lldb/trunk/source/Target/ThreadList.cpp Fri Apr 13 04:31:34 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());
 




More information about the lldb-commits mailing list