On Wed, Jul 13, 2005 at 03:51:38AM +0200, Dirk Mueller wrote:
> And this patch fixes it: 
>
> --- lib/diagnostics.pm
> +++ lib/diagnostics.pm
> @@ -503,7 +503,7 @@
>             print STDERR $warning;
>         }
>      } 
> -    goto &$oldwarn if defined $oldwarn and $oldwarn and $oldwarn ne 
> \&warn_trap;
> +    &$oldwarn if defined $oldwarn and $oldwarn and $oldwarn ne \&warn_trap;
>  };
>  
>  sub death_trap {

No, that goto is important.  It ensures the old warning handler is called
in the same caller context as when diagnostics.pm is not there.

  #!/usr/bin/perl -w

  BEGIN { $SIG{__WARN__} = sub { print join "\n", caller, @_ } }
  use diagnostics;

  warn "foo";

If you run that with and without "use diagnostics" the output from the
__WARN__ handler should be the same, it should think its called from line
6.  With your patch it thinks its called from inside diagnostics.pm.

The problem is the use of goto &foo inside a __WARN__ when &foo also calls
warn().  I suspect whatever magic that keeps warn() from calling 
$SIG{__WARN__} when its already inside one is lost.

  #!/sw/bin/perl -w

  my $warn = sub { warn(join "\n", caller, @_) };

  $SIG{__WARN__} = sub {
      # &$warn;      # this is ok
      goto &$warn;   # this segfaults
  };

  warn "foo";


-- 
Michael G Schwern     [EMAIL PROTECTED]     http://www.pobox.com/~schwern
Reality is that which, when you stop believing in it, doesn't go away.
        -- Phillip K. Dick

Reply via email to