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 <zequa...@google.com> Date: Mon, 15 Apr 2024 16:30:38 -0400 Subject: [PATCH 1/5] [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 <zequa...@google.com> Date: Tue, 16 Apr 2024 11:45:35 -0400 Subject: [PATCH 2/5] 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) ) >From 735b8d22f763c38d6e5833dd56a6bf29f84325be Mon Sep 17 00:00:00 2001 From: Zequan Wu <zequa...@google.com> Date: Tue, 16 Apr 2024 14:13:18 -0400 Subject: [PATCH 3/5] Update to use `Target::ModulesDidLoad`. --- lldb/include/lldb/Target/Target.h | 3 --- .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 6 ++---- lldb/source/Target/Target.cpp | 17 +++++++---------- .../TestModuleLoadedNotifys.py | 10 +++++++++- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 3554ef0ea5a140..2c2e6b2831ccee 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -878,9 +878,6 @@ 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 901fa53682da8e..a4fddf2eaae6f1 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -575,12 +575,10 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { true /* notify */)) { 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); + target.ModulesDidLoad(module_list); + m_interpreter_module = module_sp; return module_sp; } return nullptr; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index ec2dea5cc238d3..09b0ac42631d1a 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -1687,13 +1687,6 @@ 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) { @@ -1701,7 +1694,8 @@ void Target::ModulesDidLoad(ModuleList &module_list) { ModuleSP module_sp(module_list.GetModuleAtIndex(idx)); LoadScriptingResourceForModule(module_sp, this); } - UpdateBreakpoints(module_list, true, false); + m_breakpoint_list.UpdateBreakpoints(module_list, true, false); + m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false); if (m_process_sp) { m_process_sp->ModulesDidLoad(module_list); } @@ -1719,7 +1713,8 @@ void Target::SymbolsDidLoad(ModuleList &module_list) { } } - UpdateBreakpoints(module_list, true, false); + m_breakpoint_list.UpdateBreakpoints(module_list, true, false); + m_internal_breakpoint_list.UpdateBreakpoints(module_list, true, false); auto data_sp = std::make_shared<TargetEventData>(shared_from_this(), module_list); BroadcastEvent(eBroadcastBitSymbolsLoaded, data_sp); @@ -1732,7 +1727,9 @@ 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); - UpdateBreakpoints(module_list, false, delete_locations); + m_breakpoint_list.UpdateBreakpoints(module_list, false, delete_locations); + m_internal_breakpoint_list.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/target-new-solib-notifications/TestModuleLoadedNotifys.py b/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py index abf761fb3420b4..34c1f81316383a 100644 --- a/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py +++ b/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py @@ -7,6 +7,7 @@ from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil +import re class ModuleLoadedNotifysTestCase(TestBase): @@ -70,6 +71,7 @@ def test_launch_notifications(self): total_modules_added_events = 0 total_modules_removed_events = 0 already_loaded_modules = [] + ld_name_pattern = re.compile("^ld.*\.so") while listener.GetNextEvent(event): if lldb.SBTarget.EventIsTargetEvent(event): if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded: @@ -83,8 +85,14 @@ def test_launch_notifications(self): # will be loaded again when dyld moves itself into the # shared cache. Use the basename so this also works # when reading dyld from the expanded shared cache. + # On linux, ld.so will be loaded only once, but the + # broadcaster event will be sent twice. + module.file.basename exe_basename = lldb.SBFileSpec(exe).basename - if module.file.basename not in ["dyld", exe_basename]: + if module.file.basename not in [ + "dyld", + exe_basename, + ] and not ld_name_pattern.match(module.file.basename): self.assertNotIn( module, already_loaded_modules, >From 7cf26285a4d75a639d4bbdbf361187c809a5569f Mon Sep 17 00:00:00 2001 From: Zequan Wu <zequa...@google.com> Date: Wed, 17 Apr 2024 13:11:55 -0400 Subject: [PATCH 4/5] disable first notification --- .../POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 4 +++- .../TestModuleLoadedNotifys.py | 10 +--------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index a4fddf2eaae6f1..074cab976e96f9 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -572,9 +572,11 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { ModuleSpec module_spec(file, target.GetArchitecture()); if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, - true /* notify */)) { + false /* notify */)) { UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, false); + // Manually notify that dynamic linker is loaded after updating load section + // addersses so that breakpoints can be resolved. ModuleList module_list; module_list.Append(module_sp); target.ModulesDidLoad(module_list); diff --git a/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py b/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py index 34c1f81316383a..abf761fb3420b4 100644 --- a/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py +++ b/lldb/test/API/functionalities/target-new-solib-notifications/TestModuleLoadedNotifys.py @@ -7,7 +7,6 @@ from lldbsuite.test.decorators import * from lldbsuite.test.lldbtest import * from lldbsuite.test import lldbutil -import re class ModuleLoadedNotifysTestCase(TestBase): @@ -71,7 +70,6 @@ def test_launch_notifications(self): total_modules_added_events = 0 total_modules_removed_events = 0 already_loaded_modules = [] - ld_name_pattern = re.compile("^ld.*\.so") while listener.GetNextEvent(event): if lldb.SBTarget.EventIsTargetEvent(event): if event.GetType() == lldb.SBTarget.eBroadcastBitModulesLoaded: @@ -85,14 +83,8 @@ def test_launch_notifications(self): # will be loaded again when dyld moves itself into the # shared cache. Use the basename so this also works # when reading dyld from the expanded shared cache. - # On linux, ld.so will be loaded only once, but the - # broadcaster event will be sent twice. - module.file.basename exe_basename = lldb.SBFileSpec(exe).basename - if module.file.basename not in [ - "dyld", - exe_basename, - ] and not ld_name_pattern.match(module.file.basename): + if module.file.basename not in ["dyld", exe_basename]: self.assertNotIn( module, already_loaded_modules, >From 407b6dfa540229ad98816514eef3d8f23a8a73bb Mon Sep 17 00:00:00 2001 From: Zequan Wu <zequa...@google.com> Date: Wed, 17 Apr 2024 16:02:47 -0400 Subject: [PATCH 5/5] address comments --- .../DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 074cab976e96f9..9fa245fc41d40c 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -571,8 +571,10 @@ ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() { FileSpec file(info.GetName().GetCString()); ModuleSpec module_spec(file, target.GetArchitecture()); - if (ModuleSP module_sp = target.GetOrCreateModule(module_spec, - false /* notify */)) { + // Don't notify that module is added here because its loading section + // addresses are not updated yet. We manually notify it below. + if (ModuleSP module_sp = + target.GetOrCreateModule(module_spec, /*notify=*/false)) { UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base, false); // Manually notify that dynamic linker is loaded after updating load section _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits