#785197 emacsen-common: "tsort: -: input contains a loop:" during installation

#785197#5
Date:
2015-05-13 10:25:25 UTC
From:
To:
During the postinst, I observed the following:

Setting up semi (1.14.7~0.20120428-17) ...
tsort: -: input contains a loop:
tsort: apel
tsort: flim
tsort: emacsen-common
tsort: -: input contains a loop:
tsort: emacsen-common
tsort: flim
Install apel for emacs24
install/apel: already byte-compiled for emacs24, skipped
Install emacsen-common for emacs24
emacsen-common: Handling install of emacsen flavor emacs24
Wrote /etc/emacs24/site-start.d/00debian-vars.elc
Wrote /usr/share/emacs24/site-lisp/debian-startup.elc
Install flim for emacs24
install/flim: already byte-compiled for emacs24, skipped
Install semi for emacs24
install/semi: byte-compiling for emacs24, logged in /tmp/elc.y7mlgo7hBiVt
install/semi: deleting /tmp/elc.y7mlgo7hBiVt
install/semi: byte-compiling for reverse dependency

which is a little bizarre.

   Julian

#785197#10
Date:
2015-05-15 13:12:14 UTC
From:
To:
reassign 785197 emacsen-common 2.0.8
retitle 785197 emacsen-common: "tsort: -: input contains a loop:" during installation
thanks

I just did an upgrade (testing) on another machine, and got the same
report about semi.  I did a further upgrade on the original machine
and obtained a very similar report, this time about a different
package:

Setting up w3m-el (1.4.538+0.20141022-2) ...
tsort: -: input contains a loop:
tsort: apel
tsort: emacsen-common
Install apel for emacs24
[...]

It seems that tsort is being called by /usr/lib/emacsen-common/lib.pl
so I'm reassigning this bug to emacsen-common.

   Julian

#785197#23
Date:
2025-09-02 05:40:29 UTC
From:
To:
Observed today as well:

Best regards,
Niels

#785197#28
Date:
2026-04-16 22:40:11 UTC
From:
To:
I just ran into the same issue. In my case, the problem occured when
/usr/lib/emacsen-common/emacsen-common got called during the
installation of an inofficial emacs-snapshot package via
https://github.com/rrthomas/src-emacs-on-debian. But that is not
important.

I'm currently trying to improve src-emacs-on-debian project and thus did
many subsequent emacs-snapshot installs. The interesting thing is, that
the error only occurs sporadically. It is the result of running:

   /usr/lib/emacsen-common/emacsen-common emacs-snapshot

Which can be done outside of an actual package install. As mentioned
earlier, the actual error is from /usr/lib/emacsen-common/lib.pl which
gets used by emacsen-common. As far as I can tell, the function in
lib.pl which generates the error is `reorder_add_on_packages(..)`. I added
a debug prints while running in a loop:

sub reorder_add_on_packages
{
  my($pkglist, $installed_add_ons) = @_;
  my @depends = generate_relevant_tsort_dependencies($pkglist,
                                                     $installed_add_ons,
                                                     {});
  print @depends;        # <--- added for debugging ----------------------
  my $pid = open(TSORT, "-|");
  die "Couldn't fork for tsort: $!" unless defined($pid);

  # What a strange idiom...
  if($pid == 0) {
    my $sub_pid = open(IN, "|-");
    die "Couldn't sub-fork for tsort: $!" unless defined($sub_pid);
    if($sub_pid == 0) {
      exec 'tsort' or die "Couldn't run tsort: $!";
    }
    print IN @depends;
    exit 0;
  }
  my @ordered_pkgs = <TSORT>;
  chomp @ordered_pkgs;
  return @ordered_pkgs
}

Here is what I got in the good case:

latex-cjk-thai latex-cjk-thai
latex-cjk-common latex-cjk-thai
emacsen-common latex-cjk-thai
latex-cjk-common latex-cjk-common
emacsen-common latex-cjk-common
dictionaries-common dictionaries-common
emacsen-common dictionaries-common
emacsen-common emacsen-common
emacsen-common emacsen-common

The error case has an addional line:

latex-cjk-thai latex-cjk-thai
latex-cjk-common latex-cjk-thai
emacsen-common latex-cjk-thai
emacsen-common emacsen-common
latex-cjk-common emacsen-common     # <--- additional line -----------------
emacsen-common emacsen-common
latex-cjk-common latex-cjk-common
emacsen-common latex-cjk-common
dictionaries-common dictionaries-common
emacsen-common dictionaries-common

This additiona line: `latex-cjk-common emacsen-common` together with
`emacsen-common latex-cjk-common` is probably the loop tsort complains
about (I guess).

That's s far as I got.

#785197#33
Date:
2026-04-17 11:31:46 UTC
From:
To:
Hello again,

I think I found the root cause of this bug.

The code in `generate_relevant_tsort_dependencies_internals()` was using the result
of a regex capture group without checking for an actual regex match. Or better:
it tried to check, but got it wrong. As a result, capture groups
from (potential) previous matches were getting reused.

As I already wrote in message #28, the *tsort error* only happened
sporadically. The reason for this is, that Perl 5.18 introduced hash
randomization (see section *Hash overhaul* in
https://perldoc.perl.org/perl5180delta). This causes the order of
packages in the return value of `get_installed_add_on_packages()` to
change randomly. Which then affects if and which 'leftover' capture
groups get reused in `generate_relevant_tsort_dependencies_internals()`

By running

  generate_add_on_install_list(get_installed_add_on_packages());

in a loop [1], I could easily reproduce the `tsort: -: input contains a loop:`
errors. After applying the attached patch, those errors completely
disappeared.

BR, Kai

#785197#38
Date:
2026-04-17 11:31:46 UTC
From:
To:
Just sending the patch again, this time as real attachment (instead
of inline).