[Lldb-commits] [lldb] Fix a crasher when using the public API. (PR #80508)

Greg Clayton via lldb-commits lldb-commits at lists.llvm.org
Tue Feb 6 12:31:42 PST 2024


https://github.com/clayborg updated https://github.com/llvm/llvm-project/pull/80508

>From c416b6f4c0a00684057947782413b66af4c197f3 Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Fri, 2 Feb 2024 15:30:40 -0800
Subject: [PATCH 1/2] Fix a crasher when using the public API.

A user found a crash when they would do code like:
(lldb) script
>>> target = lldb.SBTarget()
>>> lldb.debugger.SetSelectedTarget(target)

We were not checking if the target was valid in SBDebugger::SetSelectedTarget(...).
---
 lldb/source/API/SBDebugger.cpp                   | 14 +++++++-------
 lldb/test/API/python_api/target/TestTargetAPI.py |  6 ++++++
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index fbcf30e67fc1c..12cbe25a540eb 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -1089,9 +1089,9 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
   Log *log = GetLog(LLDBLog::API);
 
   TargetSP target_sp(sb_target.GetSP());
-  if (m_opaque_sp) {
+  if (m_opaque_sp && target_sp)
     m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp);
-  }
+
   if (log) {
     SBStream sstr;
     sb_target.GetDescription(sstr, eDescriptionLevelBrief);
@@ -1704,20 +1704,20 @@ SBDebugger::LoadTraceFromFile(SBError &error,
 
 void SBDebugger::RequestInterrupt() {
   LLDB_INSTRUMENT_VA(this);
-  
+
   if (m_opaque_sp)
-    m_opaque_sp->RequestInterrupt();  
+    m_opaque_sp->RequestInterrupt();
 }
 void SBDebugger::CancelInterruptRequest()  {
   LLDB_INSTRUMENT_VA(this);
-  
+
   if (m_opaque_sp)
-    m_opaque_sp->CancelInterruptRequest();  
+    m_opaque_sp->CancelInterruptRequest();
 }
 
 bool SBDebugger::InterruptRequested()   {
   LLDB_INSTRUMENT_VA(this);
-  
+
   if (m_opaque_sp)
     return m_opaque_sp->InterruptRequested();
   return false;
diff --git a/lldb/test/API/python_api/target/TestTargetAPI.py b/lldb/test/API/python_api/target/TestTargetAPI.py
index c8e1904428c8a..63d34340a8836 100644
--- a/lldb/test/API/python_api/target/TestTargetAPI.py
+++ b/lldb/test/API/python_api/target/TestTargetAPI.py
@@ -526,3 +526,9 @@ def test_is_loaded(self):
                 target.IsLoaded(module),
                 "Running the target should " "have loaded its modules.",
             )
+
+    @no_debug_info_test
+    def test_setting_selected_target_with_invalid_target(self):
+        """Make sure we don't crash when trying to select invalid target."""
+        target = lldb.SBTarget()
+        self.dbg.SetSelectedTarget(target)

>From 1473e88ff82ea45a76e1ab65ef471c78c0bc4f70 Mon Sep 17 00:00:00 2001
From: Greg Clayton <clayborg at gmail.com>
Date: Tue, 6 Feb 2024 12:27:58 -0800
Subject: [PATCH 2/2] Do the target check in TargetList::SetSelectedTarget()
 and also check if the target is valid.

---
 lldb/source/API/SBDebugger.cpp    |  2 +-
 lldb/source/Target/TargetList.cpp | 16 ++++++++++------
 2 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index 12cbe25a540eb..6a204228cb440 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -1089,7 +1089,7 @@ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
   Log *log = GetLog(LLDBLog::API);
 
   TargetSP target_sp(sb_target.GetSP());
-  if (m_opaque_sp && target_sp)
+  if (m_opaque_sp)
     m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp);
 
   if (log) {
diff --git a/lldb/source/Target/TargetList.cpp b/lldb/source/Target/TargetList.cpp
index 121b6253d2a59..bfab46b7ea61f 100644
--- a/lldb/source/Target/TargetList.cpp
+++ b/lldb/source/Target/TargetList.cpp
@@ -532,9 +532,13 @@ void TargetList::SetSelectedTarget(uint32_t index) {
 }
 
 void TargetList::SetSelectedTarget(const TargetSP &target_sp) {
-  std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
-  auto it = llvm::find(m_target_list, target_sp);
-  SetSelectedTargetInternal(std::distance(m_target_list.begin(), it));
+  // Don't allow an invalid target shared pointer or a target that has been
+  // destroyed to become the selected target.
+  if (target_sp && target_sp->IsValid()) {
+    std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
+    auto it = llvm::find(m_target_list, target_sp);
+    SetSelectedTargetInternal(std::distance(m_target_list.begin(), it));
+  }
 }
 
 lldb::TargetSP TargetList::GetSelectedTarget() {
@@ -564,15 +568,15 @@ bool TargetList::AnyTargetContainsModule(Module &module) {
         m_in_process_target_list.insert(target_sp);
     assert(was_added && "Target pointer was left in the in-process map");
   }
-  
+
   void TargetList::UnregisterInProcessTarget(TargetSP target_sp) {
     std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
     [[maybe_unused]] bool was_present =
         m_in_process_target_list.erase(target_sp);
     assert(was_present && "Target pointer being removed was not registered");
   }
-  
+
   bool TargetList::IsTargetInProcess(TargetSP target_sp) {
     std::lock_guard<std::recursive_mutex> guard(m_target_list_mutex);
-    return m_in_process_target_list.count(target_sp) == 1; 
+    return m_in_process_target_list.count(target_sp) == 1;
   }



More information about the lldb-commits mailing list