How to leave perl debug API programmatically?

Viewed 61

I have following script:

#!/usr/bin/env perl
sub bar { foo() }
sub foo { }
sub hello { bar(); }
hello();

I run it with non-interactive debugger and got:

$ PERL5OPT=-d PERLDB_OPTS='N f=1' perl 2.pl
Package 2.pl.
  entering DB::Obj::_init
  entering main::hello
   entering main::bar
    entering main::foo

Now I want to stop printing stacktrace by disabling debugger after bar() call. How to do that ?

What I tried:

#!/usr/bin/env perl
sub bar {
# $^D;                                  # no effect
# DB::done();                           # Undefined subroutine &DB::done
# $DB::finished=1;                      # no effect
# delete $INC{'perl5db.pl'};            # no effect
# Class::Unload->unload('perl5db.pl');  # no effect
foo();
}
sub foo { }
sub hello { bar(); }
hello();

But entering main::foo still printed.

Expected output:

Package 2.pl.
  entering DB::Obj::_init
  entering main::hello
   entering main::bar
2 Answers

You can't really disable the debugger once it's started. You can, however, stop the printing of subroutine calls.

For example:

#!/usr/bin/env perl
sub bar {
    $DB::frame = 0;
    foo();
}
sub foo { }
sub hello { bar(); }
hello();

Output:

Package try.pl.
  entering DB::Obj::_init
  entering main::hello
   entering main::bar

If you want to use the big hammer and redefine DB::sub, you need to do something like this:

sub bar {
    {
        package DB;
        no warnings 'redefine';
        no strict;
        *sub = sub { &$sub };
    }
    foo();
}

However, this also means you can't re-enable call tracing at a later point in the script.

Got it! Seems like we can just clear DB::sub : *DB::sub = sub {};

$ cat 2.pl
#!/usr/bin/env perl
sub bar {
*DB::sub = sub {};
foo();
}
sub foo { }
sub hello { bar(); }
hello();

$ PERL5OPT=-d PERLDB_OPTS='NonStop frame=1' perl 2.pl
Package 2.pl.
  entering DB::Obj::_init
  entering main::hello
   entering main::bar

Thanks to Enbugger perldoc.

Related