diff --git a/lldb/include/lldb/API/SBProcessInfo.h b/lldb/include/lldb/API/SBProcessInfo.h index b3120bf5374ee..408ee85dfecab 100644 --- a/lldb/include/lldb/API/SBProcessInfo.h +++ b/lldb/include/lldb/API/SBProcessInfo.h @@ -30,6 +30,10 @@ class LLDB_API SBProcessInfo { SBFileSpec GetExecutableFile(); + /// If the process was laumched with a first argument that doesn't match + /// the executable file or name, this will return a valid string. + const char *GetArg0(); + lldb::pid_t GetProcessID(); uint32_t GetUserID(); diff --git a/lldb/source/API/SBProcessInfo.cpp b/lldb/source/API/SBProcessInfo.cpp index d9ff526ad2aca..4e0f73ae5b010 100644 --- a/lldb/source/API/SBProcessInfo.cpp +++ b/lldb/source/API/SBProcessInfo.cpp @@ -73,6 +73,15 @@ SBFileSpec SBProcessInfo::GetExecutableFile() { return file_spec; } +const char *SBProcessInfo::GetArg0() { + LLDB_INSTRUMENT_VA(this); + + if (!m_opaque_up) + return nullptr; + + return ConstString(m_opaque_up->GetArg0()).GetCString(); +} + lldb::pid_t SBProcessInfo::GetProcessID() { LLDB_INSTRUMENT_VA(this); diff --git a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp index 6db4d99ccbdba..70d24c45552dd 100644 --- a/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp +++ b/lldb/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp @@ -997,6 +997,11 @@ void DynamicLoaderPOSIXDYLD::ResolveExecutableModule( ModuleSpec module_spec(process_info.GetExecutableFile(), process_info.GetArchitecture()); + // See if the process has UUID info for the executable. If this is a core + // file we really want the UUID in the module spec so we don't load a + // random executable with the same name from the current system and ignore + // the required UUID. + m_process->FindModuleUUID(module_spec); if (module_sp && module_sp->MatchesModuleSpec(module_spec)) return; diff --git a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp index ced84ab829772..4cc760de54a5c 100644 --- a/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp @@ -1238,13 +1238,35 @@ bool ProcessElfCore::GetProcessInfo(ProcessInstanceInfo &info) { info.Clear(); info.SetProcessID(GetID()); info.SetArchitecture(GetArchitecture()); + ModuleSpec exe_module_spec; + bool added_executable = false; lldb::ModuleSP module_sp = GetTarget().GetExecutableModule(); + const bool add_exe_file_as_first_arg = true; if (module_sp) { - const bool add_exe_file_as_first_arg = false; info.SetExecutableFile(GetTarget().GetExecutableModule()->GetFileSpec(), add_exe_file_as_first_arg); + added_executable = true; + } else { + ModuleSpec exe_module_spec; + if (GetMainExecutableModuleSpec(exe_module_spec)) { + if (exe_module_spec.GetFileSpec()) { + info.SetExecutableFile(exe_module_spec.GetFileSpec(), + add_exe_file_as_first_arg); + added_executable = true; + } + } + } + Args process_args = m_process_args.as_args(); + bool first_arg_is_executable = true; + if (added_executable) { + // Strip the executable name from the process args as it can be a symlink + // that doesn't match the executable we would have created from a call to + // GetMainExecutableModuleSpec(...). + first_arg_is_executable = false; + info.SetArg0(process_args.GetArgumentAtIndex(0)); + process_args.DeleteArgumentAtIndex(0); } - info.SetArguments(m_process_args.as_args(), /*first_arg_is_executable=*/true); + info.SetArguments(process_args, first_arg_is_executable); return true; } diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py index fc79ae98e5b73..f211ac4454209 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -1453,7 +1453,17 @@ def test_exe_name_extraction_nt_file(self): target = self.dbg.CreateTarget(None) process = target.LoadCore(core_path) exe_module = target.modules[0] - self.assertEqual(exe_module.GetFileSpec().fullpath, "/path/nt_file_foo") + exe_path = "/path/nt_file_foo" + symlink_path = "/path/prpsinfo_foo" + self.assertEqual(exe_module.GetFileSpec().fullpath, exe_path) + + # Verify that the process info is correct. + process_info = target.process.GetProcessInfo() + self.assertEqual(process_info.GetName(), "nt_file_foo") + self.assertEqual(process_info.GetArg0(), symlink_path) + self.assertEqual(process_info.GetExecutableFile().fullpath, exe_path) + self.assertEqual(process_info.GetNumArguments(), 1) + self.assertEqual(process_info.GetArgumentAtIndex(0), "--verbose") self.dbg.DeleteTarget(target) @skipIfLLVMTargetMissing("X86") @@ -1472,7 +1482,18 @@ def test_exe_name_extraction_at_execfn(self): target = self.dbg.CreateTarget(None) process = target.LoadCore(core_path) exe_module = target.modules[0] - self.assertEqual(exe_module.GetFileSpec().fullpath, "/path/execfn_foo") + exe_path = "/path/execfn_foo" + symlink_path = "/path/prpsinfo_foo" + self.assertEqual(exe_module.GetFileSpec().fullpath, exe_path) + + # Verify that the process info is correct. + process_info = target.process.GetProcessInfo() + self.assertEqual(process_info.GetName(), "execfn_foo") + self.assertEqual(process_info.GetArg0(), symlink_path) + self.assertEqual(process_info.GetExecutableFile().fullpath, exe_path) + self.assertEqual(process_info.GetNumArguments(), 1) + self.assertEqual(process_info.GetArgumentAtIndex(0), "--verbose") + self.dbg.DeleteTarget(target) @skipIfLLVMTargetMissing("X86") @@ -1488,7 +1509,18 @@ def test_exe_name_extraction_nt_prpsinfo(self): target = self.dbg.CreateTarget(None) process = target.LoadCore(core_path) exe_module = target.modules[0] - self.assertEqual(exe_module.GetFileSpec().fullpath, "prpsinfo_foo") + exe_path = "prpsinfo_foo" + symlink_path = "/path/prpsinfo_foo" + self.assertEqual(exe_module.GetFileSpec().fullpath, exe_path) + + process_info = target.process.GetProcessInfo() + self.assertEqual(process_info.GetName(), exe_path) + self.assertEqual(process_info.GetArg0(), symlink_path) + self.assertEqual(process_info.GetExecutableFile().fullpath, exe_path) + self.assertEqual(process_info.GetNumArguments(), 1) + self.assertEqual(process_info.GetArgumentAtIndex(0), "--verbose") + + self.dbg.DeleteTarget(target)