eugene updated this revision to Diff 129216.
eugene marked an inline comment as done.
eugene added a comment.

Addressing code review comments.  Switching  from manual symbol resolution to 
the appropriate overload of CreateBreakpoint.


https://reviews.llvm.org/D41533

Files:
  
packages/Python/lldbsuite/test/functionalities/breakpoint/global_constructor/TestBreakpointInGlobalConstructor.py
  packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
  source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
  source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h

Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
@@ -85,13 +85,17 @@
   /// mapped to the address space
   lldb::addr_t m_vdso_base;
 
+  /// Contains AT_BASE, which means a dynamic loader has been
+  /// mapped to the address space
+  lldb::addr_t m_interpreter_base;
+
   /// Loaded module list. (link map for each module)
   std::map<lldb::ModuleWP, lldb::addr_t, std::owner_less<lldb::ModuleWP>>
       m_loaded_modules;
 
-  /// Enables a breakpoint on a function called by the runtime
+  /// If possible sets a breakpoint on a function called by the runtime
   /// linker each time a module is loaded or unloaded.
-  virtual void SetRendezvousBreakpoint();
+  bool SetRendezvousBreakpoint();
 
   /// Callback routine which updates the current list of loaded modules based
   /// on the information supplied by the runtime linker.
@@ -138,7 +142,11 @@
   /// of all dependent modules.
   virtual void LoadAllCurrentModules();
 
-  void LoadVDSO(lldb_private::ModuleList &modules);
+  void LoadVDSO();
+
+  // Loading an interpreter module (if present) assumming m_interpreter_base
+  // already points to its base address.
+  lldb::ModuleSP LoadInterpreterModule();
 
   /// Computes a value for m_load_offset returning the computed address on
   /// success and LLDB_INVALID_ADDRESS on failure.
@@ -148,9 +156,10 @@
   /// success and LLDB_INVALID_ADDRESS on failure.
   lldb::addr_t GetEntryPoint();
 
-  /// Evaluate if Aux vectors contain vDSO information
+  /// Evaluate if Aux vectors contain vDSO and LD information
   /// in case they do, read and assign the address to m_vdso_base
-  void EvalVdsoStatus();
+  /// and m_interpreter_base.
+  void EvalSpecialModulesStatus();
 
   /// Loads Module from inferior process.
   void ResolveExecutableModule(lldb::ModuleSP &module_sp);
Index: source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
===================================================================
--- source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -79,7 +79,8 @@
     : DynamicLoader(process), m_rendezvous(process),
       m_load_offset(LLDB_INVALID_ADDRESS), m_entry_point(LLDB_INVALID_ADDRESS),
       m_auxv(), m_dyld_bid(LLDB_INVALID_BREAK_ID),
-      m_vdso_base(LLDB_INVALID_ADDRESS) {}
+      m_vdso_base(LLDB_INVALID_ADDRESS),
+      m_interpreter_base(LLDB_INVALID_ADDRESS) {}
 
 DynamicLoaderPOSIXDYLD::~DynamicLoaderPOSIXDYLD() {
   if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
@@ -117,7 +118,7 @@
                               : "<null executable>",
                 load_offset);
 
-  EvalVdsoStatus();
+  EvalSpecialModulesStatus();
 
   // if we dont have a load address we cant re-base
   bool rebase_exec = (load_offset == LLDB_INVALID_ADDRESS) ? false : true;
@@ -207,7 +208,7 @@
 
   executable = GetTargetExecutable();
   load_offset = ComputeLoadOffset();
-  EvalVdsoStatus();
+  EvalSpecialModulesStatus();
 
   if (executable.get() && load_offset != LLDB_INVALID_ADDRESS) {
     ModuleList module_list;
@@ -217,7 +218,12 @@
     if (log)
       log->Printf("DynamicLoaderPOSIXDYLD::%s about to call ProbeEntry()",
                   __FUNCTION__);
-    ProbeEntry();
+
+    if (!SetRendezvousBreakpoint()) {
+      // If we cannot establish rendezvous breakpoint right now
+      // we'll try again at entry point.
+      ProbeEntry();
+    }
 
     m_process->GetTarget().ModulesDidLoad(module_list);
   }
@@ -329,38 +335,75 @@
   return false; // Continue running.
 }
 
-void DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
+bool DynamicLoaderPOSIXDYLD::SetRendezvousBreakpoint() {
   Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+  if (m_dyld_bid != LLDB_INVALID_BREAK_ID) {
+    LLDB_LOG(log,
+             "Rendezvous breakpoint breakpoint id {0} for pid {1}"
+             "is already set.",
+             m_dyld_bid,
+             m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+    return true;
+  }
 
-  addr_t break_addr = m_rendezvous.GetBreakAddress();
+  addr_t break_addr;
   Target &target = m_process->GetTarget();
-
-  if (m_dyld_bid == LLDB_INVALID_BREAK_ID) {
-    if (log)
-      log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
-                  " setting rendezvous break address at 0x%" PRIx64,
-                  __FUNCTION__,
-                  m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
-                  break_addr);
-    Breakpoint *dyld_break =
-        target.CreateBreakpoint(break_addr, true, false).get();
-    dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
-    dyld_break->SetBreakpointKind("shared-library-event");
-    m_dyld_bid = dyld_break->GetID();
+  BreakpointSP dyld_break;
+  if (m_rendezvous.IsValid()) {
+    break_addr = m_rendezvous.GetBreakAddress();
+    LLDB_LOG(log, "Setting rendezvous break address for pid {0} at {1:x}",
+             m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
+             break_addr);
+    dyld_break = target.CreateBreakpoint(break_addr, true, false);
   } else {
-    if (log)
-      log->Printf("DynamicLoaderPOSIXDYLD::%s pid %" PRIu64
-                  " reusing break id %" PRIu32 ", address at 0x%" PRIx64,
-                  __FUNCTION__,
-                  m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID,
-                  m_dyld_bid, break_addr);
+    LLDB_LOG(log, "Rendezvous structure is not set up yet. "
+                  "Trying to locate rendezvous breakpoint in the interpreter "
+                  "by symbol name.");
+    ModuleSP interpreter = LoadInterpreterModule();
+    if (!interpreter) {
+      LLDB_LOG(log, "Can't find interpreter, rendezvous breakpoint isn't set.");
+      return false;
+    }
+
+    static std::vector<std::string> DebugStateCandidates{
+        "_dl_debug_state", "rtld_db_dlactivity", "__dl_rtld_db_dlactivity",
+        "r_debug_state",   "_r_debug_state",     "_rtld_debug_state",
+    };
+
+    FileSpecList containingModules;
+    containingModules.Append(interpreter->GetFileSpec());
+    dyld_break = target.CreateBreakpoint(
+        &containingModules, nullptr /* containingSourceFiles */,
+        DebugStateCandidates, eFunctionNameTypeFull, eLanguageTypeC,
+        0,           /* offset */
+        eLazyBoolNo, /* skip_prologue */
+        true,        /* internal */
+        false /* request_hardware */);
+  }
+
+  if (dyld_break->GetNumResolvedLocations() != 1) {
+    LLDB_LOG(
+        log,
+        "Rendezvous breakpoint has abnormal number of"
+        " resolved locations ({0}) in pid {1}. It's supposed to be exactly 1.",
+        dyld_break->GetNumResolvedLocations(),
+        m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+    target.RemoveBreakpointByID(dyld_break->GetID());
+    return false;
   }
 
-  // Make sure our breakpoint is at the right address.
-  assert(target.GetBreakpointByID(m_dyld_bid)
-             ->FindLocationByAddress(break_addr)
-             ->GetBreakpoint()
-             .GetID() == m_dyld_bid);
+  BreakpointLocationSP location = dyld_break->GetLocationAtIndex(0);
+  LLDB_LOG(log,
+           "Successfully set rendezvous breakpoint at address {0:x} "
+           "for pid {1}",
+           location->GetLoadAddress(),
+           m_process ? m_process->GetID() : LLDB_INVALID_PROCESS_ID);
+
+  dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+  dyld_break->SetBreakpointKind("shared-library-event");
+  m_dyld_bid = dyld_break->GetID();
+  return true;
 }
 
 bool DynamicLoaderPOSIXDYLD::RendezvousBreakpointHit(
@@ -485,7 +528,7 @@
   return thread_plan_sp;
 }
 
-void DynamicLoaderPOSIXDYLD::LoadVDSO(ModuleList &modules) {
+void DynamicLoaderPOSIXDYLD::LoadVDSO() {
   if (m_vdso_base == LLDB_INVALID_ADDRESS)
     return;
 
@@ -506,13 +549,38 @@
   }
 }
 
+ModuleSP DynamicLoaderPOSIXDYLD::LoadInterpreterModule() {
+  if (m_interpreter_base == LLDB_INVALID_ADDRESS)
+    return nullptr;
+
+  MemoryRegionInfo info;
+  Target &target = m_process->GetTarget();
+  Status status = m_process->GetMemoryRegionInfo(m_interpreter_base, info);
+  if (status.Fail() || info.GetMapped() != MemoryRegionInfo::eYes ||
+      info.GetName().IsEmpty()) {
+    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+    LLDB_LOG(log, "Failed to get interpreter region info: {0}", status);
+    return nullptr;
+  }
+
+  FileSpec file(info.GetName().GetCString(), false);
+  ModuleSpec module_spec(file, target.GetArchitecture());
+
+  if (ModuleSP module_sp = target.GetSharedModule(module_spec)) {
+    UpdateLoadedSections(module_sp, LLDB_INVALID_ADDRESS, m_interpreter_base,
+                         false);
+    return module_sp;
+  }
+  return nullptr;
+}
+
 void DynamicLoaderPOSIXDYLD::LoadAllCurrentModules() {
   DYLDRendezvous::iterator I;
   DYLDRendezvous::iterator E;
   ModuleList module_list;
+  Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
 
   if (!m_rendezvous.Resolve()) {
-    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
     if (log)
       log->Printf("DynamicLoaderPOSIXDYLD::%s unable to resolve POSIX DYLD "
                   "rendezvous address",
@@ -524,7 +592,7 @@
   // that ourselves here.
   ModuleSP executable = GetTargetExecutable();
   m_loaded_modules[executable] = m_rendezvous.GetLinkMapAddress();
-  LoadVDSO(module_list);
+  LoadVDSO();
 
   std::vector<FileSpec> module_names;
   for (I = m_rendezvous.begin(), E = m_rendezvous.end(); I != E; ++I)
@@ -536,6 +604,8 @@
     ModuleSP module_sp =
         LoadModuleAtAddress(I->file_spec, I->link_addr, I->base_addr, true);
     if (module_sp.get()) {
+      LLDB_LOG(log, "LoadAllCurrentModules loading module: {0}",
+               I->file_spec.GetFilename());
       module_list.Append(module_sp);
     } else {
       Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
@@ -575,11 +645,14 @@
   return m_load_offset;
 }
 
-void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
-  AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
-
-  if (I != m_auxv->end())
+void DynamicLoaderPOSIXDYLD::EvalSpecialModulesStatus() {
+  auto I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
+  if (I != m_auxv->end() && I->value != 0)
     m_vdso_base = I->value;
+
+  I = m_auxv->FindEntry(AuxVector::AUXV_AT_BASE);
+  if (I != m_auxv->end() && I->value != 0)
+    m_interpreter_base = I->value;
 }
 
 addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
Index: packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
+++ packages/Python/lldbsuite/test/functionalities/load_unload/TestLoadUnload.py
@@ -368,7 +368,6 @@
 
     @skipIfFreeBSD  # llvm.org/pr14424 - missing FreeBSD Makefiles/testcase support
     @skipIfWindows  # Windows doesn't have dlopen and friends, dynamic libraries work differently
-    @unittest2.expectedFailure("llvm.org/pr25806")
     def test_static_init_during_load(self):
         """Test that we can set breakpoints correctly in static initializers"""
 
@@ -395,19 +394,19 @@
         self.runCmd("continue")
         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                     substrs=['stopped',
-                             'a_init',
-                             'stop reason = breakpoint %d' % a_init_bp_num])
+                             'b_init',
+                             'stop reason = breakpoint %d' % b_init_bp_num])
         self.expect("thread backtrace",
-                    substrs=['a_init',
+                    substrs=['b_init',
                              'dlopen',
                              'main'])
 
         self.runCmd("continue")
         self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
                     substrs=['stopped',
-                             'b_init',
-                             'stop reason = breakpoint %d' % b_init_bp_num])
+                             'a_init',
+                             'stop reason = breakpoint %d' % a_init_bp_num])
         self.expect("thread backtrace",
-                    substrs=['b_init',
+                    substrs=['a_init',
                              'dlopen',
                              'main'])
Index: packages/Python/lldbsuite/test/functionalities/breakpoint/global_constructor/TestBreakpointInGlobalConstructor.py
===================================================================
--- packages/Python/lldbsuite/test/functionalities/breakpoint/global_constructor/TestBreakpointInGlobalConstructor.py
+++ packages/Python/lldbsuite/test/functionalities/breakpoint/global_constructor/TestBreakpointInGlobalConstructor.py
@@ -17,23 +17,23 @@
     mydir = TestBase.compute_mydir(__file__)
     NO_DEBUG_INFO_TESTCASE = True
 
-    def setUp(self):
-        TestBase.setUp(self)
+    def test(self):
+        self.build()
         self.line_foo = line_number('foo.cpp', '// !BR_foo')
         self.line_main = line_number('main.cpp', '// !BR_main')
 
-    @expectedFailureAll(bugnumber="llvm.org/pr35480", oslist=["linux"])
-    def test(self):
-        self.build()
-        exe = os.path.join(os.getcwd(), "a.out")
-        self.runCmd("file %s" % exe)
+        target = self.dbg.CreateTarget("a.out")
+        self.assertTrue(target, VALID_TARGET)
+
+        env= self.registerSharedLibrariesWithTarget(target, ["foo"])
 
         bp_main = lldbutil.run_break_set_by_file_and_line(
             self, 'main.cpp', self.line_main)
         bp_foo = lldbutil.run_break_set_by_file_and_line(
             self, 'foo.cpp', self.line_foo)
 
-        self.runCmd("run")
+        process = target.LaunchSimple(
+            None, env, self.get_process_working_directory())
 
         self.assertIsNotNone(
             lldbutil.get_one_thread_stopped_at_breakpoint_id(
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to