[Lldb-commits] [lldb] [lldb][DynamicLoader] Fix lldb unable to stop at _dl_debug_state if user set it before the process launched. (PR #88792)

Zequan Wu via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 16 08:46:12 PDT 2024


https://github.com/ZequanWu updated https://github.com/llvm/llvm-project/pull/88792

>From 26528cd679478448edf446e0e82e5f207ffd6113 Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Mon, 15 Apr 2024 16:30:38 -0400
Subject: [PATCH 1/2] [lldb][DynamicLoader] Fix lldb unable to stop at
 _dl_debug_state if user set it before the process launched.

---
 lldb/include/lldb/Target/Target.h               |  3 +++
 .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp       |  5 +++++
 lldb/source/Target/Target.cpp                   | 17 ++++++++++-------
 .../breakpoint_command/TestBreakpointCommand.py | 17 +++++++++++++++++
 4 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 2c2e6b2831ccee..3554ef0ea5a140 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -878,6 +878,9 @@ class Target : public std::enable_shared_from_this<Target>,
   // the address of its previous instruction and return that address.
   lldb::addr_t GetBreakableLoadAddress(lldb::addr_t addr);
 
+  void UpdateBreakpoints(ModuleList &module_list, bool added,
+                         bool delete_locations);
+
   void ModulesDidLoad(ModuleList &module_list);
 
   void ModulesDidUnload(ModuleList &module_list, bool delete_locations);
diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 9baf86da4dc799..901fa53682da8e 100644
--- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -576,6 +576,11 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
     UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base,
                          false);
     m_interpreter_module = module_sp;
+    // Manually update breakpoints after updating loaded sections, because they
+    // cannot be resolve at the time when creating this module.
+    ModuleList module_list;
+    module_list.Append(module_sp);
+    m_process->GetTarget().UpdateBreakpoints(module_list, true, false);
     return module_sp;
   }
   return nullptr;
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 09b0ac42631d1a..ec2dea5cc238d3 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -1687,6 +1687,13 @@ void Target::NotifyModulesRemoved(lldb_private::ModuleList &module_list) {
   ModulesDidUnload(module_list, false);
 }
 
+void Target::UpdateBreakpoints(ModuleList &module_list, bool added,
+                               bool delete_locations) {
+  m_breakpoint_list.UpdateBreakpoints(module_list, added, delete_locations);
+  m_internal_breakpoint_list.UpdateBreakpoints(module_list, added,
+                                               delete_locations);
+}
+
 void Target::ModulesDidLoad(ModuleList &module_list) {
   const size_t num_images = module_list.GetSize();
   if (m_valid && num_images) {
@@ -1694,8 +1701,7 @@ void Target::ModulesDidLoad(ModuleList &module_list) {
       ModuleSP module_sp(module_list.GetModuleAtIndex(idx));
       LoadScriptingResourceForModule(module_sp, this);
     }
-    m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
-    m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
+    UpdateBreakpoints(module_list, true, false);
     if (m_process_sp) {
       m_process_sp->ModulesDidLoad(module_list);
     }
@@ -1713,8 +1719,7 @@ void Target::SymbolsDidLoad(ModuleList &module_list) {
       }
     }
 
-    m_breakpoint_list.UpdateBreakpoints(module_list, true, false);
-    m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false);
+    UpdateBreakpoints(module_list, true, false);
     auto data_sp =
         std::make_shared<TargetEventData>(shared_from_this(), module_list);
     BroadcastEvent(eBroadcastBitSymbolsLoaded, data_sp);
@@ -1727,9 +1732,7 @@ void Target::ModulesDidUnload(ModuleList &module_list, bool delete_locations) {
     auto data_sp =
         std::make_shared<TargetEventData>(shared_from_this(), module_list);
     BroadcastEvent(eBroadcastBitModulesUnloaded, data_sp);
-    m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations);
-    m_internal_breakpoint_list.UpdateBreakpoints(module_list, false,
-                                                 delete_locations);
+    UpdateBreakpoints(module_list, false, delete_locations);
 
     // If a module was torn down it will have torn down the 'TypeSystemClang's
     // that we used as source 'ASTContext's for the persistent variables in
diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
index ea242952e409ec..a7e23fae14a21f 100644
--- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -671,3 +671,20 @@ def test_breakpoint_statistics_hitcount(self):
         self.assertNotEqual(breakpoints_stats, None)
         for breakpoint_stats in breakpoints_stats:
             self.assertIn("hitCount", breakpoint_stats)
+
+    @skipIf(oslist=no_match(["linux"]))
+    def test_break_at__dl_debug_state(self):
+        """
+        Test lldb is able to stop at _dl_debug_state if it is set before the
+        process is launched.
+        """
+        self.build()
+        exe = self.getBuildArtifact("a.out")
+        self.runCmd("target create %s" % exe)
+        bpid = lldbutil.run_break_set_by_symbol(self, "_dl_debug_state",
+                                                num_expected_locations=0)
+        self.runCmd("run")
+        self.assertIsNotNone(
+            lldbutil.get_one_thread_stopped_at_breakpoint_id(self.process(),
+                                                             bpid)
+        )

>From 29d5861f1748c2f71c9d699b670dc393a9bf6710 Mon Sep 17 00:00:00 2001
From: Zequan Wu <zequanwu at google.com>
Date: Tue, 16 Apr 2024 11:45:35 -0400
Subject: [PATCH 2/2] format

---
 .../breakpoint_command/TestBreakpointCommand.py           | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
index a7e23fae14a21f..850235fdcefa70 100644
--- a/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
+++ b/lldb/test/API/functionalities/breakpoint/breakpoint_command/TestBreakpointCommand.py
@@ -681,10 +681,10 @@ def test_break_at__dl_debug_state(self):
         self.build()
         exe = self.getBuildArtifact("a.out")
         self.runCmd("target create %s" % exe)
-        bpid = lldbutil.run_break_set_by_symbol(self, "_dl_debug_state",
-                                                num_expected_locations=0)
+        bpid = lldbutil.run_break_set_by_symbol(
+            self, "_dl_debug_state", num_expected_locations=0
+        )
         self.runCmd("run")
         self.assertIsNotNone(
-            lldbutil.get_one_thread_stopped_at_breakpoint_id(self.process(),
-                                                             bpid)
+            lldbutil.get_one_thread_stopped_at_breakpoint_id(self.process(), bpid)
         )



More information about the lldb-commits mailing list