Subject: 27.0.50; Warn pdumper users when pure space has been overflowed

From: Kévin Le Gouguec <[email-masked]>
Date: Wed, 04 Dec 2019 20:02:12 +0100

Hello,

For some reason, one of my setups[1] experiences a pure storage overflow
with the current master[2].  Searching previous bug reports for the
warning[3] led me to understand that increasing BASE_PURESIZE in
src/puresize.h would solve the issue; since I didn't have the patience
to recompile possibly multiple times, I tried to find a way to know
exactly how much I should increase this value.

I noticed that Fdump_emacs uses check_pure_size from alloc.c to print a
warning before dumping when this happens.  The following patch exposes
check_pure_size when we HAVE_PDUMPER, so that Fdump_emacs_portable can
use it too.

>From 02a48f2388932ae78460a76f74e27202212994d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?K=C3=A9vin=20Le=20Gouguec?= <[email-masked]>
Date: Wed, 4 Dec 2019 18:22:29 +0100
Subject: [PATCH] Warn pdumper users when pure space has been overflowed

* src/alloc.c (check_pure_size): Expose when using the portable
dumper.
* src/pdumper.c (Fdump_emacs_portable): Use it.
---
 src/alloc.c   | 2 +-
 src/pdumper.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/alloc.c b/src/alloc.c
index 9fbd0d0573..52ea87c7b7 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -5125,7 +5125,7 @@ pure_alloc (size_t size, int type)
 }

-#ifdef HAVE_UNEXEC
+#if defined HAVE_UNEXEC || defined HAVE_PDUMPER
 
 /* Print a warning if PURESIZE is too small.  */
 
diff --git a/src/pdumper.c b/src/pdumper.c
index 74f198c4ae..721d23e696 100644
--- a/src/pdumper.c
+++ b/src/pdumper.c
@@ -4004,6 +4004,8 @@ DEFUN ("dump-emacs-portable",
 {
   eassert (initialized);
 
+  check_pure_size ();
+
   if (will_dump_with_unexec_p ())
     error ("This Emacs instance was started under the assumption "
            "that it would be dumped with unexec, not the portable "
-- 
2.20.1

That gets me a helpful error message at compile-time[4] (as well as an
intriguing warning[5]) that let me figure out how much I should increase
BASE_PURESIZE by, recompile Emacs and run it with no further warnings
about pure storage overflow.

Would it make sense to apply this?  (Maybe not as-is: e.g. I don't know
if the #if guard is still useful at this point; maybe the call to
check_pure_size should be moved somewhere else…)

Thank you for your time.

[1] Debian Buster on Samsung NC10 (32-bit, 2GB RAM).

[2] 8bea7e9ab4453da71d9766d582089154f31de907

[3] Warning (initialization): Building Emacs overflowed pure space.  (See the node Pure Storage in the Lisp manual for details.)

[4] emacs:0:Pure Lisp storage overflow (approx. 2005404 bytes needed)

[5] alloc.c:5136:14: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘intmax_t’ {aka ‘long long int’} [-Wformat=]
         message (("emacs:0:Pure Lisp storage overflow (approx. %"pI"d"
                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            " bytes needed)"),
            ~~~~~~~~~~~~~~~~~

    I tried to puzzle this one out by looking at the definition for pI
    in lisp.h, but I am not sure how to proceed.  The warning suggests
    that pI is defined as "" since the final format is %d, which means
    that I should look into this snippet:

    # elif INTPTR_MAX <= INT_MAX && !defined WIDE_EMACS_INT
    typedef int EMACS_INT;
    typedef unsigned int EMACS_UINT;
    enum { EMACS_INT_WIDTH = INT_WIDTH, EMACS_UINT_WIDTH = UINT_WIDTH };
    #  define EMACS_INT_MAX INT_MAX
    #  define pI ""

    … I can probably dig into this to see what's wrong on my setup[1],
    but I'll bank on someone more experienced going "Oh well duh" and
    fixing whatever needs fixing (assuming the problem isn't on my end).

In GNU Emacs 27.0.50 (build 11, i686-pc-linux-gnu, GTK+ Version 3.24.5, cairo version 1.16.0)
 of 2019-11-17 built on little-buster
Repository revision: 1c29ba034092660e73bce8c6ff459c75ff2c2d72
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12004000
System Description: Debian GNU/Linux 10 (buster)

Configured using:
 'configure --with-xwidgets --with-cairo'

Configured features:
XPM JPEG TIFF GIF PNG RSVG CAIRO SOUND GPM DBUS GSETTINGS GLIB NOTIFY
INOTIFY ACL LIBSELINUX GNUTLS LIBXML2 FREETYPE HARFBUZZ M17N_FLT LIBOTF
ZLIB TOOLKIT_SCROLL_BARS GTK3 X11 XDBE XIM MODULES THREADS XWIDGETS
LIBSYSTEMD JSON PDUMPER LCMS2 GMP

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Features:
(shadow sort mail-extr emacsbug sendmail etags fileloop generator xref
vc-mtn vc-hg mule-util warnings filecache markdown-mode rx color
noutline outline help-fns radix-tree magit-extras sh-script smie
flyspell ispell executable cus-edit wid-edit whitespace notifications
dbus xml misearch multi-isearch bug-reference cc-mode cc-fonts cc-guess
cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs thingatpt
magit-submodule magit-obsolete magit-blame magit-stash magit-reflog
magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote
magit-commit magit-sequence magit-notes magit-worktree magit-tag
magit-merge magit-branch magit-reset magit-files magit-refs magit-status
magit magit-repos magit-apply magit-wip magit-log which-func imenu
magit-diff smerge-mode magit-core magit-autorevert autorevert filenotify
magit-margin magit-transient magit-process magit-mode git-commit
magit-git magit-section magit-utils crm log-edit message rmc puny dired
dired-loaddefs rfc822 mml mml-sec epa derived epg epg-config gnus-util
rmail rmail-loaddefs text-property-search time-date mm-decode mm-bodies
mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util ietf-drums
mail-prsvr mailabbrev mail-utils gmm-utils mailheader pcvs-util add-log
with-editor async-bytecomp async shell pcomplete server dash vc-git
vc-bzr vc-src vc-sccs vc-svn vc-cvs vc-rcs project delight
eighters-theme rg rg-info-hack advice rg-menu transient cl-extra
format-spec rg-ibuffer rg-result wgrep-rg wgrep s rg-history rg-header
ibuf-ext ibuffer ibuffer-loaddefs grep compile comint ansi-color ring
quail help-mode edmacro kmacro disp-table paren mb-depth icomplete
page-break-lines elec-pair diff-hl-flydiff diff diff-hl vc-dir ewoc vc
vc-dispatcher diff-mode easy-mmode delsel cus-start cus-load tex-site
info package easymenu browse-url url-handlers url-parse auth-source
cl-seq eieio eieio-core cl-macs eieio-loaddefs password-cache json
subr-x map url-vars seq byte-opt gv bytecomp byte-compile cconv
cl-loaddefs cl-lib tooltip eldoc electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel term/x-win x-win term/common-win x-dnd tool-bar
dnd fontset image regexp-opt fringe tabulated-list replace newcomment
text-mode elisp-mode lisp-mode prog-mode register page tab-bar menu-bar
rfn-eshadow isearch timer select scroll-bar mouse jit-lock font-lock
syntax facemenu font-core term/tty-colors frame minibuffer cl-generic
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite charscript charprop
case-table epa-hook jka-cmpr-hook help simple abbrev obarray
cl-preloaded nadvice loaddefs button faces cus-face macroexp files
text-properties overlay sha1 md5 base64 format env code-pages mule
custom widget hashtable-print-readable backquote threads dbusbind
inotify lcms2 dynamic-setting system-font-setting font-render-setting
xwidget-internal cairo move-toolbar gtk x-toolkit x multi-tty
make-network-process emacs)

Memory information:
((conses 8 330562 41453)
 (symbols 24 23104 2)
 (strings 16 73924 11567)
 (string-bytes 1 2445511)
 (vectors 8 42019)
 (vector-slots 4 959888 63404)
 (floats 8 281 269)
 (intervals 28 21802 357)
 (buffers 568 52))