diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h @@ -60,6 +60,9 @@ DYLDRendezvous(lldb_private::Process *process); + /// Update the cached executable path. + void UpdateExecutablePath(); + /// Update the internal snapshot of runtime linker rendezvous and recompute /// the currently loaded modules. /// diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp @@ -94,12 +94,13 @@ : m_process(process), m_rendezvous_addr(LLDB_INVALID_ADDRESS), m_current(), m_previous(), m_loaded_modules(), m_soentries(), m_added_soentries(), m_removed_soentries() { - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); - m_thread_info.valid = false; + UpdateExecutablePath(); +} - // Cache a copy of the executable path +void DYLDRendezvous::UpdateExecutablePath() { if (m_process) { + Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER)); Module *exe_mod = m_process->GetTarget().GetExecutableModulePointer(); if (exe_mod) { m_exe_file_spec = exe_mod->GetPlatformFileSpec(); diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -102,6 +102,7 @@ ModuleSP executable_sp = GetTargetExecutable(); ResolveExecutableModule(executable_sp); + m_rendezvous.UpdateExecutablePath(); // find the main process load offset addr_t load_offset = ComputeLoadOffset(); diff --git a/lldb/test/API/commands/process/attach/TestProcessAttach.py b/lldb/test/API/commands/process/attach/TestProcessAttach.py --- a/lldb/test/API/commands/process/attach/TestProcessAttach.py +++ b/lldb/test/API/commands/process/attach/TestProcessAttach.py @@ -20,6 +20,13 @@ NO_DEBUG_INFO_TESTCASE = True + def setUp(self): + # Call super's setUp(). + TestBase.setUp(self) + # Find the line number to break for main.c. + self.line = line_number('main.cpp', + '// Waiting to be attached...') + @skipIfiOSSimulator def test_attach_to_process_by_id(self): """Test attach by process id""" @@ -77,6 +84,28 @@ process = target.GetProcess() self.assertTrue(process, PROCESS_IS_VALID) + def test_attach_to_process_by_id_correct_executable_offset(self): + """ + Test that after attaching to a process the executable offset + is determined correctly on FreeBSD. This is a regression test + for dyld plugin getting the correct executable path, + and therefore being able to identify it in the module list. + """ + + self.build() + exe = self.getBuildArtifact(exe_name) + + # In order to reproduce, we must spawn using a relative path + popen = self.spawnSubprocess(os.path.relpath(exe)) + + self.runCmd("process attach -p " + str(popen.pid)) + + # Make suer we did not attach to early + lldbutil.run_break_set_by_file_and_line( + self, "main.cpp", self.line, num_expected_locations=1, loc_exact=False) + self.runCmd("process continue") + self.expect("p g_val", substrs=["$0 = 12345"]) + def tearDown(self): # Destroy process before TestBase.tearDown() self.dbg.GetSelectedTarget().GetProcess().Destroy() diff --git a/lldb/test/API/commands/process/attach/main.cpp b/lldb/test/API/commands/process/attach/main.cpp --- a/lldb/test/API/commands/process/attach/main.cpp +++ b/lldb/test/API/commands/process/attach/main.cpp @@ -3,6 +3,8 @@ #include #include +volatile int g_val = 12345; + int main(int argc, char const *argv[]) { int temp; lldb_enable_attach();