How does a Perl script know if it's running in the debugger?
Asked Answered
O

4

5

I have a script that redirects STDIN/STDOUT to a file normally. But, debugging is a lot more efficient if it doesn't do that. Is there a $DB:xxx variable or something that lets the script know so it can behave differently?

Omaromara answered 21/5, 2020 at 12:35 Comment(2)
Do you mean the interactive debugger or Perl's debugging functionality? (see comments on answers below)Kimberlite
This was for running perl -d, shich I believe is Perl's debugging functionality.Anuran
P
4

I didn't find any way of determining if they debugger is running directly, but you could check if well-known debugger variable $DB::single exists using the following:

if ( $DB::{ single } ) {
   say "Debugger is running";
}

Another approach would be to check if the debugger module is loaded.

if ( $INC{ "perl5db.pl" } ) {
   say "Debugger is running";
}

Finally, the debugger requires that Perl is running in debug support mode, and $^P indicates whether Perl is in this mode or not.

if ( $^P ) {
   say "Perl is in debug support mode";
}

The debugger isn't the only tool that requires putting Perl in debug support mode. Others include Devel::NYTProf, Devel::Cover, Devel::Trace, and more. So this approach can't be used to specifically check if the debugger is running. But it might be what you actually want.

Practise answered 21/5, 2020 at 15:27 Comment(6)
Kudos to Eugen Konkov for bringing up $^P.Practise
(However, his answer incorrectly describes what it does.)Practise
I just pasted documentation as is.Kimberlite
@Eugen Konkov, Please consult the documentation for $^P (in perlvar) and -d (in perlrun).Practise
Please notice that $DB::single is false when we step over the function. Did you mean if( exists $DB::{ single })? You mention that in the description, but forgot in the code.Kimberlite
@Eugen Konkov, $DB::{ single } isn't the same as $DB::single. It's the same as *DB::single, except that it doesn't vivify the symbol (which would render the test useless).Practise
T
1

Reading through the perl source code of DB.pm (perldoc -m DB), I noticed that $SIG{INT} is globally set at the end.

This seems to work, at least for a trivial program:

if (\&DB::catch && $SIG{'INT'} && $SIG{'INT'} == \&DB::catch) {
    say "Debugging ?"
}

If it's not applicable, I guess it's possible to subclass DB.pm and create a simple debugger which overrides cont and does extra bookkeeping.

Teleran answered 21/5, 2020 at 13:18 Comment(0)
K
1

To find that your script is under debugger you need to check: $^P variable:

if ( $^P ) {
    # running under a debugger
}

https://perldoc.perl.org/perldebug#Calling-the-Debugger

If you script was run without -d option then $DB::single does noting.

According to the documentation the minimal debugger is sub DB::DB {}.
So another method to check that your script is under debugger is:

if( defined &DB::DB ){
   # running under a debugger
} 
Kimberlite answered 11/5, 2023 at 14:56 Comment(8)
Not quite. $^P indicates whether Perl is running in debug support mode or not, not whether the debugger is running or not. This is not quite the same. For example, $^P will be true when using Devel::Trace (perl -d:Trace ...) even though the debugger isn't running. And $DB::single won't do anything then either, since the debugger is not running. But, it could be what the OP actually wants, so +1.Practise
@ikegami: Then I completely do not understand documentation. It says running under the debugger. It seems this sections requires more description. Also perlrun said that -d:MOD runs the program under the control of a debugging. I believe, it is not possible that $DB::single won't do anything, when -d is used ( debugger Perl_init_debugger(aTHX) is initialized). perldebguts. Please correct me, If I am wrong.Kimberlite
@ikegami: Devel::Trace just do not bring interactive debugging, but that does not meant it does not make use of $DB::single and not under debugger.Kimberlite
Re "It says running under the debugger.", That is not accurate. It is running with debuggin support, as the documentation for $^P (in perlvar) says. /// Re "perlrun said that -d:MOD runs the program under the control of a debugging" module, This one is correct. Like it says -d:Trace puts Devel::Trace "in control". Devel::Trace is not the debugger. -d without a module puts the debugger "in control".Practise
Re "that does not meant it does not make use of $DB::single and not under debugger.", True, yet it's not under the debugger, and it doesn't create and use $DB::single like the debugger does.Practise
@ikegami: Thanks. Now that is much clear. -d turns on Perl's debugging functionality (eg. Perl_init_debugger( aTHX ) is called ). After that Perl inserts value of PERL5DB environment variable as first line (The line with number zero) of a script. By default it is BEGIN{ require "perl5db.pl" }. Which brings the interactive debugging. In case of -d:MOD the use Devel::MOD will be used as the first line and, I assume, PERL5DB will be ignored. Still -d:MOD runs script under debugger, but depending on MOD implementation it could be without the interactive debugging.Kimberlite
@ikegami: RE: True, yet it's not under the debugger. I think we need to clarify a bit. There are two debuggers: 1. Perl's debugger functionality and 2. the interactive debugging implemented by perl5db.pl or Devel::MOD when -d:MOD is used. When you used the debugger you mean the interactive debugging, but I mean Perl's debugging functionality.Kimberlite
Or to use the terms from the docs, there is the Perl debugger (perl5db.pl), and there is debugging support (enabled by -d). The OP asked how to detect if the debugger is being used, but your answer shows how to detect debugging support. My original comment stands.Practise
A
0

Both of these are useful for what I was doing. I'll put it on my Perl cheat sheet.

if ( $INC{ "perl5db.pl" } ) {
   say "Debugger is running";
}

if ( $^P ) {
   say "Perl is in debug support mode";
}
Anuran answered 12/5, 2023 at 17:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.