emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Finding the dump (redux)


From: Ali Bahrami
Subject: Finding the dump (redux)
Date: Thu, 15 Apr 2021 13:38:37 -0600
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:78.0) Gecko/20100101 Thunderbird/78.9.1

Hi,

    I'm a bit late to the pdump party, as we had just updated
the emacs delivered with Solaris shortly before the version
with pdumper arrived, and we don't tend to update more than once
every year or two. It's overdue though, and I've been playing with
emacs 27.2 on Solaris this week. It's great, but I find myself wanting
to request a small tweak to the search for the pdmp file.

First though, I want to say that pdumper is awesome, and has
exceeded my hopes and expectations. It seems just as fast,
and it is so nice to be out of the unexec game. Who knows,
we might someday even be able to get rid of the special dldump()
function that was written for emacs decades ago. :-) In any event,
I'm running 27.2 on my desktop as a position independent executable
(PIE) and with ASLR enabled, and everything seems to working as it
should. Thank You Daniel for persisting, and for this big step
forward!

The issue I'm hitting is similar to one discussed over 2
years ago:

     "Finding the dump"
     https://lists.gnu.org/archive/html/emacs-devel/2019-01/msg00558.html

At that time, Eli made a change to improve the way pdmp
files are found in PATH_EXEC, using the basename(argv[0])
to find matching dump files. It's useful, but not quite
enough to handle the way we deliver emacs on Solaris.

Like others, we deliver the 3 UI variants of emacs so that
users have their choice. Along with that is a "mediator" symlink,
provided by the packaging system, that provides the generic
'emacs' name, pointing at the default version. Mediators are
a Solaris feature, and there's a packaging command by which
the system owner can change them to point at their own favored
default. On my desktop, it looks like this:

     % cd /usr/bin
     % ls -alFh emacs*
     lrwxrwxrwx   1 root   root     9 Apr 14 22:15 emacs -> emacs-gtk*
     -r-xr-xr-x   2 root   bin  7.05M Apr 14 22:15 emacs-gtk*
     -r-xr-xr-x   2 root   bin  7.05M Apr 14 22:15 emacs-gtk-27.2*
     -r-xr-xr-x   2 root   bin  6.09M Apr 14 22:15 emacs-nox*
     -r-xr-xr-x   2 root   bin  6.09M Apr 14 22:15 emacs-nox-27.2*
     -r-xr-xr-x   2 root   bin  7.07M Apr 14 22:15 emacs-x*
     -r-xr-xr-x   2 root   bin  7.07M Apr 14 22:15 emacs-x-27.2*
     -r-xr-xr-x   1 root   bin    47K Apr 14 22:15 emacsclient*

And the pdmp files are similarly named, to match the
emacs executables:

     % cd /usr/lib/emacs/27.2/x86_64-pc-solaris2.11
     % ls -alhF *.pdmp
     -r--r--r--   2 root   bin  10.2M Apr 14 22:15 emacs-gtk-27.2.pdmp
     -r--r--r--   2 root   bin  10.2M Apr 14 22:15 emacs-gtk.pdmp
     -r--r--r--   2 root   bin  9.64M Apr 14 22:15 emacs-nox-27.2.pdmp
     -r--r--r--   2 root   bin  9.64M Apr 14 22:15 emacs-nox.pdmp
     -r--r--r--   2 root   bin  10.1M Apr 14 22:15 emacs-x-27.2.pdmp
     -r--r--r--   2 root   bin  10.1M Apr 14 22:15 emacs-x.pdmp

As noted, the default is emacs-gtk, but I can change that:

     # pkg set-mediator -I emacs-x emacs
     <...pkg output elided...>
     # ls -alFh /usr/bin/emacs
     rwxrwxrwx   1 root  root   7 Apr 15 11:47 /usr/bin/emacs -> emacs-x*

Like a lot of GNU/Linux distributions, we used to use a
shell script for this, but we moved to the mediator years
ago. With the new emacs, this works well for the explicitly
named versions (emacs-gtk, emacs-nox, and emacs-x). But, when
run via the 'emacs' symlink (the usual case), the binary is
unable to find its pdmp file. It still runs, but ends up
loading all the separate elc files, which is undesirable.

I can solve this without changing emacs, superficially, by just
adding a corresponding mediator symlink for emacs.pdmp in the
PATH_EXEC directory. But then, if an end user were to make their
own symlink to one of these emacs variants, they'll still face
this problem:

     % ln -s /usr/bin/emacs-gtk ~/bin/myemacs

Sure, that user could specify the pdmp file on the command
line, or wrap it in a shell script, but for default behavior,
I don't think that should be necessary. Why shouldn't an emacs,
found by whatever path, not be able to find its default pdmp file
in PATH_EXEC? I believe that the search done by emacs is just
missing a check that would solve this. The problem is that
load_pdump() in src/emacs.c only searches PATH_EXEC for
emacs.pdmp, and then for the pdmp file with the name given by:

     basename(argv[0])

If it were to also search for

     basename(realpath(argv[0]))

then it would find pdmp files that match either the given, or
"absolute" names, rather than just the given name, and symlinks
that point at emacs executables would always find the default
pdmp file that goes with them, whether we deliver them, or the
user makes their own.

I note that the discussion in 2019 spent a lot of time discussing
how realpath(argv[0])) can be unreliable, and that applications can
change argv[0]. That's true, but assuming that this is understood,
it is still useful most of the time. Note that the code in load_pdump()
already calls realpath(). It uses the result to locate the corresponding
pdmp file in the directory containing the executable. The only thing
missing is to take the next step, and apply the same information to
the search of PATH_EXEC.

It's not necessary to add more code to do this. It suffices to refactor
the existing code into a couple of functions that can be used to cover
the 2 existing cases, plus this new one. I've attached a patch to Emacs 27.2
that does that, to this message. Note however that I don't have a contributor
agreement in place, and it might be difficult for me to do that any time
soon. I'm hoping that this patch might still qualify, on the basis that
it is just a rearrangement of the existing code, and not at all novel.
Or, perhaps someone else will be willing to take the ideas and quickly
put together an official fix independently. Those ideas are:

     - Move the repeated code into functions, to clean up load_pdump().

     - Save the basename from the result of calling realpath() during the
       search of the executable directory.

     - During the PATH_EXEC stage, use the saved realpath basename to
       add a check for that name.

Thanks for your consideration.

- Ali

Attachment: mediator.patch
Description: Text document


reply via email to

[Prev in Thread] Current Thread [Next in Thread]