Index: lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h =================================================================== --- lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h +++ 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. /// Index: lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp =================================================================== --- lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp +++ 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(); Index: lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp =================================================================== --- lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -101,6 +101,7 @@ ModuleSP executable_sp = GetTargetExecutable(); ResolveExecutableModule(executable_sp); + m_rendezvous.UpdateExecutablePath(); // find the main process load offset addr_t load_offset = ComputeLoadOffset(); Index: lldb/test/API/commands/process/attach/TestProcessAttach.py =================================================================== --- lldb/test/API/commands/process/attach/TestProcessAttach.py +++ lldb/test/API/commands/process/attach/TestProcessAttach.py @@ -77,6 +77,41 @@ 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)) + + # Grab the offset and filename from the image list + m = self.match("image list -h -f", + [r"^\[\s*0\]\s*(0x[0-9a-fA-F]+)\s*([^\n]*)"]) + self.assertTrue(os.path.samefile(m.group(2), exe)) + offset_attach = m.group(1) + + target = self.dbg.GetSelectedTarget() + process = target.GetProcess() + self.assertTrue(process, PROCESS_IS_VALID) + + # Now grab the file itself and compare the offset + self.runCmd("target create " + exe) + m = self.match("image list -h -f", + [r"^\[\s*0\]\s*(0x[0-9a-fA-F]+)\s*([^\n]*)"]) + self.assertTrue(os.path.samefile(m.group(2), exe)) + offset_target = m.group(1) + + self.assertEqual(offset_attach, offset_target) + def tearDown(self): # Destroy process before TestBase.tearDown() self.dbg.GetSelectedTarget().GetProcess().Destroy()