GNU bug report logs -
#79082
30.1; [reproducibility] sysinfo call during profile dump
Previous Next
Full log
View this message in rfc822 format
> Cc: 79082 <at> debbugs.gnu.org, Liliana Marie Prikler <liliana.prikler <at> gmail.com>
> Date: Mon, 28 Jul 2025 16:13:08 +0200
> From: "Dr. Werner Fink" <werner <at> suse.de>
>
> > Hi emacs,
> >
> > I recently worked a bit on reproducibility which is not guaranteed in
> > particular in the profile dump. I found that undeterminism during the
> > profile dump comes from two sources : calls to clock_gettime and
> > sysinfo.
> >
> > clock_gettime is not that hard to patch using faketime, but it's called
> > multiple times so it'll be harder to find where in the codebase.
> >
> > We don't have dedicated tools to patch sysinfo without compiling an
> > additional file an using the same LD_PRELOAD trick as faketime, but
> > there's actually an OK solution on the lisp side, IMHO (this is what I
> > propose for guix's emacs <at> 30.1, but it'd be great to add that on the next
> > release:
> >
> > (add-after 'unpack 'avoid-sysinfo-call-at-build-time
> > (lambda _
> > ;; This is a useful trick for reproducibility: when we configured
> > ;; with --disable-build-details, (system-name) is nil at build
> > ;; time on the lisp side.
> > ;; Find those places with strace -k -e sysinfo.
> > (substitute* "lisp/jit-lock.el"
> > (("\\(condition-case nil \\(load-average\\) \\(error\\)\\)"
> > all)
> > (format #f "(and (system-name) ~a)" all)))))
> >
> > It's only a single line change (with maybe a comment addition), please
> > proceed without my feedback if I don't answer, it doesn't deserve a
> > copyright citation.
>
> After some debugging with a helper function I've identified two
> lisp objects, a Lisp Float which are set by the garbage collector,
> and a Lisp Cons set by the initial lisp timestamp at startup.
> Both are changing at every dump therefore avoid them or use
> a fixed value at dump time.
>
> During debugging I stumbled over some inconsistencies in
> pdumper.c which are already fixed in upstream master branch.
Thanks.
However, in order for us to accept these patches, they must fulfill
the following conditions:
. the special code which avoids causing the build to become not
reproducible must be conditioned on an optional variable, or at
least on some compile-time symbol (like, for example, something
derived from --disable-build-details); and
. the code changes should either be portable, or, if they are
specific to GNU/Linux, they should be conditioned on an appropriate
preprocessor macro to avoid compiling it on other platforms
> --- src/pdumper.c
> +++ src/pdumper.c 2025-07-09 07:26:00.889706813 +0000
> @@ -2140,9 +2140,9 @@ dump_interval_node (struct dump_context
> if (node->parent)
> dump_field_fixup_later (ctx, &out, node, &node->parent);
> if (node->left)
> - dump_field_fixup_later (ctx, &out, node, &node->parent);
> + dump_field_fixup_later (ctx, &out, node, &node->left);
> if (node->right)
> - dump_field_fixup_later (ctx, &out, node, &node->parent);
> + dump_field_fixup_later (ctx, &out, node, &node->right);
This code looks differently on master.
> @@ -2213,9 +2213,9 @@ dump_finalizer (struct dump_context *ctx
> /* Do _not_ call dump_pseudovector_lisp_fields here: we dump the
> only Lisp field, finalizer->function, manually, so we can give it
> a low weight. */
> - dump_field_lv (ctx, &out, finalizer, &finalizer->function, WEIGHT_NONE);
> - dump_field_finalizer_ref (ctx, &out, finalizer, &finalizer->prev);
> - dump_field_finalizer_ref (ctx, &out, finalizer, &finalizer->next);
> + dump_field_lv (ctx, out, finalizer, &finalizer->function, WEIGHT_NONE);
> + dump_field_finalizer_ref (ctx, out, finalizer, &finalizer->prev);
> + dump_field_finalizer_ref (ctx, out, finalizer, &finalizer->next);
> return finish_dump_pvec (ctx, &out->header);
This is already in the code on master.
> --- src/timefns.c
> +++ src/timefns.c 2025-07-11 07:32:33.928031852 +0000
> @@ -600,6 +600,40 @@ make_lisp_time (struct timespec t)
> Lisp_Object
> timespec_to_lisp (struct timespec t)
> {
> + if (will_dump_p()) /* Use provided epoch at dump to get reproducible pdmp images */
> + {
> + char *epoch;
> + epoch = secure_getenv("SOURCE_DATE_EPOCH");
secure_getenv is specific to glibc. If we want to use it on other
platforms, we need to import the Gnulib secure_getenv module.
We should also make sure this change doesn't interfere with the build,
since we do have code in Emacs that manipulates time and is used
during the build.
This bug report was last modified 10 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.