diff --git a/src/Common/src/Interop/Linux/procfs/Interop.ProcFsStat.cs b/src/Common/src/Interop/Linux/procfs/Interop.ProcFsStat.cs index d9d713d4c428..2b87afa3c764 100644 --- a/src/Common/src/Interop/Linux/procfs/Interop.ProcFsStat.cs +++ b/src/Common/src/Interop/Linux/procfs/Interop.ProcFsStat.cs @@ -14,13 +14,15 @@ internal static partial class Interop internal static partial class procfs { internal const string RootPath = "/proc/"; - internal const string SelfExeFilePath = RootPath + "self/exe"; - internal const string ProcUptimeFilePath = RootPath + "uptime"; + private const string ExeFileName = "/exe"; private const string StatFileName = "/stat"; private const string MapsFileName = "/maps"; private const string FileDescriptorDirectoryName = "/fd/"; private const string TaskDirectoryName = "/task/"; + internal const string SelfExeFilePath = RootPath + "self" + ExeFileName; + internal const string ProcUptimeFilePath = RootPath + "uptime"; + internal struct ParsedStat { // Commented out fields are available in the stat data file but @@ -80,6 +82,11 @@ internal struct ParsedMapsModule internal KeyValuePair AddressRange; } + internal static string GetExeFilePathForProcess(int pid) + { + return RootPath + pid.ToString(CultureInfo.InvariantCulture) + ExeFileName; + } + internal static string GetStatFilePathForProcess(int pid) { return RootPath + pid.ToString(CultureInfo.InvariantCulture) + StatFileName; diff --git a/src/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs b/src/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs index d46cda85f4d2..898cf347ec1f 100644 --- a/src/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs +++ b/src/System.Diagnostics.Process/src/System/Diagnostics/Process.Linux.cs @@ -186,9 +186,14 @@ private void SetWorkingSetLimitsCore(IntPtr? newMin, IntPtr? newMax, out IntPtr // ---- PAL layer ends here ---- // ----------------------------- - /// Gets the path to the current executable, or null if it could not be retrieved. - private static string GetExePath() + /// Gets the path to the executable for the process, or null if it could not be retrieved. + /// The pid for the target process, or -1 for the current process. + internal static string GetExePath(int processId = -1) { + string exeFilePath = processId == -1 ? + Interop.procfs.SelfExeFilePath : + Interop.procfs.GetExeFilePathForProcess(processId); + // Determine the maximum size of a path int maxPath = Interop.Sys.MaxPath; @@ -197,7 +202,7 @@ private static string GetExePath() { // Read from procfs the symbolic link to this process' executable byte[] buffer = new byte[pathLen + 1]; // +1 for null termination - int resultLength = Interop.Sys.ReadLink(Interop.procfs.SelfExeFilePath, buffer, pathLen); + int resultLength = Interop.Sys.ReadLink(exeFilePath, buffer, pathLen); // If we got one, null terminate it (readlink doesn't do this) and return the string if (resultLength > 0) diff --git a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Linux.cs b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Linux.cs index a64f50d89aa0..61e1d1f2e531 100644 --- a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Linux.cs +++ b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Linux.cs @@ -80,6 +80,22 @@ internal static ProcessModuleCollection GetModules(int processId) } } + // Move the main executable module to be the first in the list if it's not already + string exePath = Process.GetExePath(processId); + for (int i = 0; i < modules.Count; i++) + { + ProcessModule module = modules[i]; + if (module.FileName == exePath) + { + if (i > 0) + { + modules.RemoveAt(i); + modules.Insert(0, module); + } + break; + } + } + // Return the set of modules found return modules; } diff --git a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs index e370668b7cf1..6b701ec5c974 100644 --- a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs +++ b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessModuleCollection.cs @@ -27,6 +27,10 @@ internal ProcessModuleCollection(int capacity) internal void Add(ProcessModule module) => InnerList.Add(module); + internal void Insert(int index, ProcessModule module) => InnerList.Insert(index, module); + + internal void RemoveAt(int index) => InnerList.RemoveAt(index); + public ProcessModule this[int index] => (ProcessModule)InnerList[index]; public int IndexOf(ProcessModule module) => InnerList.IndexOf(module);