[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 [email protected]
>From 33013c19088fa3a43e468ef41aa0d1298e63d233 Mon Sep 17 00:00:00 2001
From: Niko Tyni <[email protected]>
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