Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process.ProcessName can return full path in spite of the documentation #21249

Open
k15tfu opened this issue Oct 14, 2021 · 2 comments
Open

Process.ProcessName can return full path in spite of the documentation #21249

k15tfu opened this issue Oct 14, 2021 · 2 comments

Comments

@k15tfu
Copy link
Contributor

k15tfu commented Oct 14, 2021

Hi!

It turned out that sometimes Process.GetCurrentProcess().ProcessName can return full path to the executable in spite of the documentation: The ProcessName property holds an executable file name, such as Outlook, that does not include the .exe extension or the path. (as per https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.process.processname?view=netframework-4.8).

Looking into the code, I see that System.Diagnostics.Process.ProcessName internally uses ves_icall_System_Diagnostics_Process_ProcessName_internal, which in its turn calls mono_w32process_module_get_name, and in some cases it uses mono_w32process_get_name:

if (procname_ext == NULL) {
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: Can't find procname_ext from procmods %p", __func__, handle);
/* If it's *still* null, we might have hit the
* case where reading /proc/$pid/maps gives an
* empty file for this user.
*/
procname_ext = mono_w32process_get_name (pid);
if (!procname_ext)
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: Can't find procname_ext from proc_get_name %p pid %d", __func__, handle, pid);
}

which is based on readlink /proc/self/exe:

memset (buf, '\0', sizeof(buf));
filename = g_strdup_printf ("/proc/%d/exe", pid);
#if defined(HAVE_READLINK)
if (readlink (filename, buf, 255) > 0) {
ret = g_strdup (buf);
}
#endif
g_free (filename);
if (ret != NULL) {
return(ret);
}

In my case this leads to No such file or directory error when I'm trying to create the logs located here: /tmp/SomeLogsFromProcessWithName{Process.GetCurrentProcess().ProcessName}#{Process.GetCurrentProcess().Id}.log

@ThomasKuehne
Copy link
Contributor

ThomasKuehne commented Dec 1, 2021

I don't see how mono_w32process_get_name could try to open /proc/self/exe,

Could you please identify what file name is actually causing No such file or directory by

  1. using a debugger or
  2. strace (available in almost all Linux distributions):
    strace --follow-forks --output=traces /usr/bin/mono test.exe
    and then searching the traces file for the relevant ENOENT (No such file or directory) error.

@k15tfu
Copy link
Contributor Author

k15tfu commented Dec 3, 2021

@ThomasKuehne Hi! There are two errors, the first is that we use too short buffer when parsing maps file, and the second is that in this case we fallback to /proc/self/exe and doesn't extract an executable name from it. Here is simple repro:

  1. Create a project with this:
using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine(Process.GetCurrentProcess().ProcessName);
        }
    }
}
  1. Build, and move to a directory with long full path (235 characters in my case)
  2. Run
user@h:~/tmp2/ConsoleApplication1/bin/Debug/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$ mono ConsoleApplication1.exe
/usr/bin/mono-sgen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants