develooper Front page | perl.perl5.porters | Postings from March 2000

Tiny 2-byte change to fix debugger's eval bug

Thread Next
From:
Tom Christiansen
Date:
March 14, 2000 21:27
Subject:
Tiny 2-byte change to fix debugger's eval bug
Message ID:
17133.953098037@chthon
Although I won't be doing any long jumping tonight to fix the
debugger's signal bug, its eval bug turned out to be easy to
fix--which is a very good thing, because it was far worse than I
had initially realized.  It turns out that any module file which
upon loading had either the foresight or audacity to run a proper
eval (eg. to test for sys-dependent features, or run conditional
loads of other modules), would for its troubles see its properly
trapped and wholly non-fatal exceptions unceremoniously folded,
spindled, and mutilated by that treacherous debugger.

Here's a simple test case that illustrates this even more sinister
aspect of the bug:

    package Mod;
    eval { die "ok\n"; };
    unless ($@ && $@ eq "ok\n") {
	die "Keep your hands off my exceptions, you freak: $@";
    } 
    1;

Perfectly harmless, eh?  Run that as 

    % perl -MMod -e 1

And you will see how all is fine.  

But *now* watch what befalls your perfectly innocent module as the
evil $SIG{__DIE__} monster blows you out of the water (and prevaricates
as it does so, too):

% perl -de 'require Mod; 1'
[...]
main::(-e:1):   require Mod; 1
  DB<1> c
Keep your hands off my exceptions, you freak: ok
        require 0 called at Mod.pm line 2
        require Mod.pm called at -e line 1
        require Mod.pm called at -e line 1
Compilation failed in require at -e line 1, <IN> line 1.
Debugged program terminated.  Use q to quit or R to restart,
  use O inhibit_exit to avoid stopping after program termination,
  h q, h R or h O to get additional info.  

And that's not even the worst of it.  Look here:

$ perl -MMod -de 0 

Keep your hands off my exceptions, you freak: ok

Cannot print stack trace, load with -MCarp option to see stack at /usr/local/lib/perl5/5.6.0/perl5db.pl line 2033.

Cannot print stack trace, load with -MCarp option to see stack at /usr/local/lib/perl5/5.6.0/perl5db.pl line 2033.
Compilation failed in require.

Cannot print stack trace, load with -MCarp option to see stack at /usr/local/lib/perl5/5.6.0/perl5db.pl line 2033.
BEGIN failed--compilation aborted.

Cannot print stack trace, load with -MCarp option to see stack at /usr/local/lib/perl5/5.6.0/perl5db.pl line 2033.

Oh what an ugly mess!

This means you may not be able to use the debugger at all in its
default configuration on any such modules, not to mention on programs
that have an eval "string" construct anywhere at all in them.  Nasty, 
nasty, nasty.

Fortunately, it only takes a *two-byte change* to alter this lunacy
back to sane mode for the default.  If people really and truly *want*
to be screwed, that's certainly their prerogative to make that
decision--for themselves--but at least then they presumably know
what they're getting into.  Getting hosed should always be optional,
never the default.

This whole rigamarole should of course in the long term be fixed
so as not to much with *any* non-fatal exception, but what's below
should, I believe, do the trick at least for now.   Well-behaved
programs and modules can again run unharmed by default as once they
did under an older, less intrusive debugger.

--- perl5db.pl-presig   Tue Mar 14 18:42:13 2000
+++ perl5db.pl  Tue Mar 14 21:21:54 2000
@@ -276,8 +276,8 @@
 
 # These guys may be defined in $ENV{PERL5DB} :
 $rl            = 1     unless defined $rl;
-$warnLevel     = 1     unless defined $warnLevel;
-$dieLevel      = 1     unless defined $dieLevel;
+$warnLevel     = 0     unless defined $warnLevel;
+$dieLevel      = 0     unless defined $dieLevel;
 $signalLevel   = 1     unless defined $signalLevel;
 $pre           = []    unless defined $pre;
 $post          = []    unless defined $post;

Here's the patch for the perldebug manpage, explaining that the
default is now sane mode, which is kinda nice because it means we
don't have to document the bug down in the BUGS section, as it's
got a band-aide and an explanation here.

diff -bu pod/perldebug.pod /tmp/perldebug.pod
--- pod/perldebug.pod   Mon Mar 13 23:39:55 2000
+++ /tmp/perldebug.pod  Tue Mar 14 19:26:47 2000
@@ -488,16 +488,23 @@
 
 =item C<signalLevel>, C<warnLevel>, C<dieLevel>
 
-Level of verbosity.  By default, the debugger prints backtraces
-upon receiving any kind of warning (this is often annoying) and
-fatal exceptions (this is often valuable).  It will attempt to print
-a message when uncaught INT, BUS, or SEGV signals arrive.
+Level of verbosity.  By default, the debugger leaves your exceptions
+and warnings alone, because altering them can break correctly running
+programs.  It will attempt to print a message when uncaught INT, BUS, or
+SEGV signals arrive.  (But see the mention of signals in L<BUGS> below.)
 
-To disable this behaviour, set these values to 0.  If C<dieLevel>
-is 2, the debugger usurps your own exception handler and prints out
-a trace of these, replacing your exceptions with its own.  This may
-be useful for some tracing purposes, but tends to hopelessly destroy
-any program that takes its exception handling seriously.
+To disable this default safe mode, set these values to something higher
+than 0.  At a level of 1, you get backtraces upon receiving any kind
+of warning (this is often annoying) or exception (this is
+often valuable).  Unfortunately, the debugger cannot discern fatal
+exceptions from non-fatal ones.  If C<dieLevel> is even 1, then your
+non-fatal exceptions are also traced and unceremoniously altered if they
+came from C<eval'd> strings or from any kind of C<eval> within modules
+you're attempting to load.  If C<dieLevel> is 2, the debugger doesn't
+care where they came from:  It usurps your exception handler and prints
+out a trace, then modifies all exceptions with its own embellishments.
+This may perhaps be useful for some tracing purposes, but tends to hopelessly
+destroy any program that takes its exception handling seriously.
 
 =item C<AutoTrace>
 

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About