Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.99k stars 557 forks source link

perl5db.pl: handling of undefined watch_expressions in _DB__handle_watch_expressions() #22207

Open hexcoder- opened 6 months ago

hexcoder- commented 6 months ago

(This is just an observation, not necessarily a bug.)

perl5db.pl as of commit https://github.com/Perl/perl5/commit/c60ffc18d95f78ee7648b195a460da80064bba28

Module: perl5db.pl

Description

Reviewing the code for _DB__handle_watch_expressions() https://github.com/Perl/perl5/blob/8cacb84717058962131a5d2a3180c34d514f2b05/lib/perl5db.pl#L2483 I found that using join here https://github.com/Perl/perl5/blob/8cacb84717058962131a5d2a3180c34d514f2b05/lib/perl5db.pl#L2494 makes $val always defined, since join always returns a (possibly empty) defined string.

Then in the following line https://github.com/Perl/perl5/blob/8cacb84717058962131a5d2a3180c34d514f2b05/lib/perl5db.pl#L2495 the false branch is never applied.

So maybe watchpoint expressions with result "undefined" are not reported correctly.

====================== My main motivation for looking here, was the behavior of watchpoints with regard to package scope changes.

In my application I had my %hash; along with some imported modules.

When my hash was populated completely (and should be constant afterwards), I wanted to see where and when $hash{'myEntry'} changed unexpectedly. But using a watchpoint w $hash{'myEntry'} in the debugger led to a lot of unwanted breaks: each time the package/module scope changed the visibility of %hash changed also, of course.

How these visibility changes can be ignored in watchpoint breaks, I do not not know yet (should this be another bug report?).

tonycoz commented 6 months ago

The visibility thing sound like a separate problem.

So maybe watchpoint expressions with result "undefined" are not reported correctly.

That looks like a regression introduced with the debugger refactor around 2012.

This changed the code from:

    my ($val) = &eval;  # Fix context (&eval is doing array)?
    $val = ( (defined $val) ? "'$val'" : 'undef' );

to what it is now:

            my ($val) = join( "', '", DB::eval(@_) );
            $val = ( ( defined $val ) ? "'$val'" : 'undef' );

I expect the fix is something like:

            my $val = join( ", ", map { defined ? "'$_'" : "undef" } DB::eval(@_) );