Subject: bug#44128: bug#47800: [native-comp] could not resolve realpath of "emacs"

From: Phil Sainty <[email-masked]>
Date: Fri, 16 Apr 2021 17:41:52 +1200

On 16/04/21 3:08 am, Eli Zaretskii wrote (on bug 47800):
> Does the untested patch below fix the problem?

That didn't change the outcomes for me.

I've just tried some very basic debugging with the attached patch
(yours plus some debug output) which gives me the following outputs:

$ cd /tmp

$ ls emacs
ls: cannot access 'emacs': No such file or directory

$ emacs --version
load_pdump_find_executable: candidate: /home/phil/bin/emacs
=> file: /home/phil/bin/emacs
=> (link) realpath: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
load_pdump: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
real_filename( /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50 )
=> realpath: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
set_invocation_vars: emacs
real_filename( emacs )
=> realpath: (null)
emacs: could not resolve realpath of "emacs": No such file or directory

$ mkdir emacs

$ emacs --version
load_pdump_find_executable: candidate: /home/phil/bin/emacs
=> file: /home/phil/bin/emacs
=> (link) realpath: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
load_pdump: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
real_filename( /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50 )
=> realpath: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
set_invocation_vars: emacs
real_filename( emacs )
=> realpath: /tmp/emacs
emacs: /tmp/../native-lisp/28.0.50-abd7aa58/preloaded/window-0d1b8b93-581f9fcd.eln: cannot open shared object file: No such file or directory

$ /home/phil/emacs/native-comp/usr/local/bin/emacs --version
load_pdump: /home/phil/emacs/native-comp/usr/local/bin/emacs
real_filename( /home/phil/emacs/native-comp/usr/local/bin/emacs )
=> realpath: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
set_invocation_vars: /home/phil/emacs/native-comp/usr/local/bin/emacs
real_filename( /home/phil/emacs/native-comp/usr/local/bin/emacs )
=> realpath: /home/phil/emacs/native-comp/usr/local/bin/emacs-28.0.50
GNU Emacs 28.0.50
Copyright (C) 2021 Free Software Foundation, Inc.
GNU Emacs comes with ABSOLUTELY NO WARRANTY.
You may redistribute copies of GNU Emacs
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING.

diff --git a/src/emacs.c b/src/emacs.c
index a256564..0503504 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -446,6 +446,7 @@ terminate_due_to_signal (int sig, int backtrace_limit)
 static char *
 real_filename (char *filename)
 {
+  fprintf (stderr, "real_filename( %s )\n", filename);
   char *real_name;
 #ifdef WINDOWSNT
   /* w32_my_exename resolves symlinks internally, so no need to
@@ -453,6 +454,7 @@ real_filename (char *filename)
   real_name = xstrdup (filename);
 #else
   real_name = realpath (filename, NULL);
+  fprintf (stderr, "=> realpath: %s\n", real_name);
   if (!real_name)
     fatal ("could not resolve realpath of \"%s\": %s",
 	   filename, strerror (errno));
@@ -495,6 +497,7 @@ set_invocation_vars (char *argv0, char const *original_pwd)
   if (! NILP (handler))
     raw_name = concat2 (slash_colon, raw_name);
 
+  fprintf (stderr, "set_invocation_vars: %s\n", SSDATA (raw_name));
   char *filename = real_filename (SSDATA (raw_name));
   raw_name = build_unibyte_string (filename);
   xfree (filename);
@@ -843,10 +846,18 @@ load_pdump_find_executable (char const *argv0, ptrdiff_t *candidate_size)
       memcpy (candidate + 0, path_part, path_part_length);
       candidate[path_part_length] = DIRECTORY_SEP;
       memcpy (candidate + path_part_length + 1, argv0, argv0_length + 1);
+      fprintf (stderr, "load_pdump_find_executable: candidate: %s\n", candidate);
       struct stat st;
       if (file_access_p (candidate, X_OK)
 	  && stat (candidate, &st) == 0 && S_ISREG (st.st_mode))
-	return candidate;
+	{
+	  fprintf (stderr, "=> file: %s\n", candidate);
+	  if (lstat (candidate, &st) == 0 && S_ISLNK (st.st_mode)) {
+	    fprintf (stderr, "=> (link) realpath: %s\n", realpath (candidate, NULL));
+	    return realpath (candidate, NULL);
+	  }
+	  return candidate;
+	}
       *candidate = '\0';
     }
   while (*path++ != '\0');
@@ -912,6 +923,7 @@ load_pdump (int argc, char **argv, char const *original_pwd)
      the dump in the hardcoded location.  */
   if (dump_file && *dump_file)
     {
+      fprintf (stderr, "load_pdump: %s\n", dump_file);
       char *real_exename = real_filename (dump_file);
       xfree (dump_file);
       dump_file = real_exename;