[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

Reply via email to