Skip to content

[lldb] Implement bidirectional access for backing<->backed thread relationship #125300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

felipepiovezan
Copy link
Contributor

This enables finding the backed thread from the backing thread without going through the thread list, and it will be useful for subsequent commits.

…ationship

This enables finding the backed thread from the backing thread without
going through the thread list, and it will be useful for subsequent
commits.
@llvmbot
Copy link
Member

llvmbot commented Jan 31, 2025

@llvm/pr-subscribers-lldb

Author: Felipe de Azevedo Piovezan (felipepiovezan)

Changes

This enables finding the backed thread from the backing thread without going through the thread list, and it will be useful for subsequent commits.


Full diff: https://github.com/llvm/llvm-project/pull/125300.diff

5 Files Affected:

  • (modified) lldb/include/lldb/Target/Thread.h (+15)
  • (modified) lldb/include/lldb/Target/ThreadList.h (-2)
  • (modified) lldb/source/Plugins/Process/Utility/ThreadMemory.h (+6-1)
  • (modified) lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (+1-1)
  • (modified) lldb/source/Target/ThreadList.cpp (-14)
diff --git a/lldb/include/lldb/Target/Thread.h b/lldb/include/lldb/Target/Thread.h
index ef66fa11574db9..d5fe33586fa3cf 100644
--- a/lldb/include/lldb/Target/Thread.h
+++ b/lldb/include/lldb/Target/Thread.h
@@ -470,6 +470,18 @@ class Thread : public std::enable_shared_from_this<Thread>,
 
   virtual void ClearStackFrames();
 
+  /// Derived classes implementing SetBackingThread should use this to provide
+  /// bidirectional access to the Backing-Backed relationship.
+  void SetBackedThread(Thread &backed_thread) {
+    assert(backed_thread.GetBackingThread().get() == this);
+    m_backed_thread = backed_thread.shared_from_this();
+  }
+
+  void ClearBackedThread() { m_backed_thread.reset(); }
+
+  /// Returns the thread that is backed by this thread, if any.
+  lldb::ThreadSP GetBackedThread() const { return m_backed_thread; }
+
   virtual bool SetBackingThread(const lldb::ThreadSP &thread_sp) {
     return false;
   }
@@ -1349,6 +1361,9 @@ class Thread : public std::enable_shared_from_this<Thread>,
   LazyBool m_override_should_notify;
   mutable std::unique_ptr<ThreadPlanStack> m_null_plan_stack_up;
 
+  /// The Thread backed by this thread, if any.
+  lldb::ThreadSP m_backed_thread;
+
 private:
   bool m_extended_info_fetched; // Have we tried to retrieve the m_extended_info
                                 // for this thread?
diff --git a/lldb/include/lldb/Target/ThreadList.h b/lldb/include/lldb/Target/ThreadList.h
index f931bb83a8ceaf..bca01f5fe2083e 100644
--- a/lldb/include/lldb/Target/ThreadList.h
+++ b/lldb/include/lldb/Target/ThreadList.h
@@ -101,8 +101,6 @@ class ThreadList : public ThreadCollection {
 
   lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);
 
-  lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);
-
   bool ShouldStop(Event *event_ptr);
 
   Vote ShouldReportStop(Event *event_ptr);
diff --git a/lldb/source/Plugins/Process/Utility/ThreadMemory.h b/lldb/source/Plugins/Process/Utility/ThreadMemory.h
index d124f5780ea9bd..1e309671e85c65 100644
--- a/lldb/source/Plugins/Process/Utility/ThreadMemory.h
+++ b/lldb/source/Plugins/Process/Utility/ThreadMemory.h
@@ -72,12 +72,17 @@ class ThreadMemory : public lldb_private::Thread {
 
   void ClearStackFrames() override;
 
-  void ClearBackingThread() override { m_backing_thread_sp.reset(); }
+  void ClearBackingThread() override {
+    if (m_backing_thread_sp)
+      m_backing_thread_sp->ClearBackedThread();
+    m_backing_thread_sp.reset();
+  }
 
   bool SetBackingThread(const lldb::ThreadSP &thread_sp) override {
     // printf ("Thread 0x%llx is being backed by thread 0x%llx\n", GetID(),
     // thread_sp->GetID());
     m_backing_thread_sp = thread_sp;
+    thread_sp->SetBackedThread(*this);
     return (bool)thread_sp;
   }
 
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 21a0fa283644d6..3f34ea2930a66a 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1728,7 +1728,7 @@ ThreadSP ProcessGDBRemote::SetThreadStopInfo(
     thread_sp->SetStopInfo(StopInfoSP());
     // If there's a memory thread backed by this thread, we need to use it to
     // calculate StopInfo.
-    if (ThreadSP memory_thread_sp = m_thread_list.GetBackingThread(thread_sp))
+    if (ThreadSP memory_thread_sp = thread_sp->GetBackedThread())
       thread_sp = memory_thread_sp;
 
     if (exc_type != 0) {
diff --git a/lldb/source/Target/ThreadList.cpp b/lldb/source/Target/ThreadList.cpp
index 6cbef330bf4888..c0440d82fd1ffc 100644
--- a/lldb/source/Target/ThreadList.cpp
+++ b/lldb/source/Target/ThreadList.cpp
@@ -191,20 +191,6 @@ ThreadSP ThreadList::GetThreadSPForThreadPtr(Thread *thread_ptr) {
   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());
 

if (m_backing_thread_sp)
m_backing_thread_sp->ClearBackedThread();
m_backing_thread_sp.reset();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really wanted to make ClearBackedThread a protected member of Thread, but then we can't access it here. Protected only works if you're going through this.

@@ -470,6 +470,18 @@ class Thread : public std::enable_shared_from_this<Thread>,

virtual void ClearStackFrames();

/// Derived classes implementing SetBackingThread should use this to provide
/// bidirectional access to the Backing-Backed relationship.
void SetBackedThread(Thread &backed_thread) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have an assert that's requiring that backed_thread has to have had its backing thread set first, then passed to this API. Would it be a more user-friendly API if it set the backed_thread's backing thread here, if it isn't already set.
It's still fine to assert if somebody set the wrong backing thread, that seems like an unintended error. But if the backed_thread.GetBackingThread was null, is there any reason not to set it for them here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, this also addresses my concern of people calling SetBackedThread without also calling SetBackingThread. Will update.

Copy link
Collaborator

@jimingham jimingham left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@labath
Copy link
Collaborator

labath commented Feb 3, 2025

This creates a shared_pointer loop between the two objects, which doesn't sound like a good design. Maybe one of the pointers ought to be weak?

@felipepiovezan
Copy link
Contributor Author

Reference in new issue

This creates a shared_pointer loop between the two objects, which doesn't sound like a good design. Maybe one of the pointers ought to be weak?

great catch!, I'll fix that

@felipepiovezan
Copy link
Contributor Author

felipepiovezan commented Feb 3, 2025

Turns out github has been stuck for hours without picking up my pushed fixup commit :/
image

@felipepiovezan felipepiovezan force-pushed the felipe/bidirection_backing_backed branch from 2a83cea to 1882d04 Compare February 3, 2025 20:47
@felipepiovezan
Copy link
Contributor Author

Forcing push seems to have made it work

@felipepiovezan felipepiovezan merged commit 90a51a4 into llvm:main Feb 3, 2025
7 checks passed
@felipepiovezan felipepiovezan deleted the felipe/bidirection_backing_backed branch February 3, 2025 21:41
felipepiovezan added a commit to felipepiovezan/llvm-project that referenced this pull request Feb 3, 2025
…ationship (llvm#125300)

This enables finding the backed thread from the backing thread without
going through the thread list, and it will be useful for subsequent
commits.

(cherry picked from commit 90a51a4)
Icohedron pushed a commit to Icohedron/llvm-project that referenced this pull request Feb 11, 2025
…ationship (llvm#125300)

This enables finding the backed thread from the backing thread without
going through the thread list, and it will be useful for subsequent
commits.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants