[Lldb-commits] [lldb] r329891 - Don't assume backing thread shares protocol ID.

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Thu Apr 12 02:58:20 PDT 2018


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());
 




More information about the lldb-commits mailing list