[apt-cacher maintainers: the context here is that URI.pm introduced an optional dependency on Regexp::IPv6 by requiring it in an eval block, but the apt-cacher __DIE__ handler exits when the require fails.]
On Mon, Jul 11, 2022 at 05:35:17PM +0200, gregor herrmann wrote: > So we have: > - do nothing > - patch URI to restart the default signal handler in the eval > - (reassign? and) do something in apt-cacher I'm not really sure if there's a consensus on best practices around $SIG{__DIE__}. IMO apt-cacher is the one that should be fixed, rather than demanding that all the modules it uses need to reset and restore $SIG{__DIE__} before catching exceptions. >From 'perldoc -f die' : You can arrange for a callback to be run just before the "die" does its deed, by setting the $SIG{__DIE__} hook. The associated handler is called with the exception as an argument, and can change the exception, if it sees fit, by calling "die" again. See "%SIG" in perlvar for details on setting %SIG entries, and "eval" for some examples. Although this feature was to be run only right before your program was to exit, this is not currently so: the $SIG{__DIE__} hook is currently called even inside "eval"ed blocks/strings! If one wants the hook to do nothing in such situations, put die @_ if $^S; as the first line of the handler (see "$^S" in perlvar). Because this promotes strange action at a distance, this counterintuitive behavior may be fixed in a future release. Corresponding untested patch against apt-cacher attached. -- Niko Tyni nt...@debian.org
>From 33013c19088fa3a43e468ef41aa0d1298e63d233 Mon Sep 17 00:00:00 2001 From: Niko Tyni <nt...@debian.org> Date: Mon, 11 Jul 2022 21:18:43 +0300 Subject: [PATCH] Handle eval blocks in unsuspecting libraries $SIG{__DIE__} can get called from eval blocks - don't bail out if so. Bug-Debian: https://bugs.debian.org/1014730 --- apt-cacher | 1 + 1 file changed, 1 insertion(+) diff --git a/apt-cacher b/apt-cacher index a8c00cb..8c1fe88 100755 --- a/apt-cacher +++ b/apt-cacher @@ -1253,6 +1253,7 @@ sub write_error_log { } sub die_handler { + die @_ if $^S; # called from an eval block my ($msg) = @_; write_error_log("error [$$]: $msg"); sendrsp(HTTP::Response->new(502, 'apt-cacher internal error (died)', ['Connection' => 'close'])) if $con; -- 2.30.2