Skip to content

Commit

Permalink
signatures: generate only one debug breakable line for signatures
Browse files Browse the repository at this point in the history
With the debugger enabled the argcheck op and each argelem op
generated to process a function signature would have an associated
dbstate op, allowing the debugger to step on that op.

This can be confusing and/or onerous when stepping through code, since
for a signature with 7 arguments you'd have 9 steps to get past the
prologue of the sub.

Make most of these dbstates into nextstates to make them non-steppable.

Fixes Perl#22602
  • Loading branch information
tonycoz committed Sep 19, 2024
1 parent 55a059e commit 1c2da39
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 10 deletions.
29 changes: 29 additions & 0 deletions lib/perl5db.t
Original file line number Diff line number Diff line change
Expand Up @@ -3662,6 +3662,35 @@ EOS
$wrapper->contents_like(qr/print "2\\n"/, "break immediately after defining problem");
}

{
my $wrapper = DebugWrap->new(
{
cmds =>
[
"s",
"s",
"s",
"s",
"s",
"s",
"s",
"q",
],
prog => \<<'EOS',
use v5.40.0;
sub four ($x1, $x2, $x3, $x4) { # start sub four
print $x1, $x2, $x3, $x4;
}
four(1,2,3,4);
EOS
}
);
my $content = $wrapper->_contents;
my $count = () = $content =~ /start sub four/g;
is($count, 1, "expect to step on sub four entry once")
or diag $content;
}

done_testing();

END {
Expand Down
3 changes: 2 additions & 1 deletion op.c
Original file line number Diff line number Diff line change
Expand Up @@ -8896,7 +8896,8 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
flags &= ~SVf_UTF8;

NewOp(1101, cop, 1, COP);
if (PERLDB_LINE && CopLINE(PL_curcop) && PL_curstash != PL_debstash) {
if (PERLDB_LINE && CopLINE(PL_curcop) && PL_curstash != PL_debstash &&
!(flags & OPf_FORCE_NEXTSTATE)) {
OpTYPE_set(cop, OP_DBSTATE);
}
else {
Expand Down
7 changes: 7 additions & 0 deletions op.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ Deprecated. Use C<GIMME_V> instead.
op_convert_list to set op_folded. */
#define OPf_FOLDED (1<<16)

/* force newSTATEOP() to make an OP_NEXTSTATE.
This is useful if you need to intro_my() but not make a breakable
op.
*/
#define OPf_FORCE_NEXTSTATE (1 << 17)

/* old names; don't use in new code, but don't break them, either */
#define OPf_LIST OPf_WANT_LIST
#define OPf_KNOW OPf_WANT
Expand Down
8 changes: 4 additions & 4 deletions perly.act

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion perly.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion perly.tab

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions perly.y
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ sigslurpelem: sigslurpsigil sigvarname sigdefault/* def only to catch errors */
yyerror("A slurpy parameter may not have "
"a default value");

$$ = var ? newSTATEOP(0, NULL, var) : NULL;
$$ = var ? newSTATEOP(OPf_FORCE_NEXTSTATE, NULL, var) : NULL;
}
;

Expand Down Expand Up @@ -913,7 +913,7 @@ sigscalarelem:
"follows optional parameter");
}

$$ = var ? newSTATEOP(0, NULL, var) : NULL;
$$ = var ? newSTATEOP(OPf_FORCE_NEXTSTATE, NULL, var) : NULL;
}
;

Expand Down Expand Up @@ -985,7 +985,7 @@ subsigguts:
(UNOP_AUX_item *)aux);
sigops = op_prepend_elem(OP_LINESEQ, check, sigops);
sigops = op_prepend_elem(OP_LINESEQ,
newSTATEOP(0, NULL, NULL),
newSTATEOP(OPf_FORCE_NEXTSTATE, NULL, NULL),
sigops);
/* a nextstate at the end handles context
* correctly for an empty sub body */
Expand Down

0 comments on commit 1c2da39

Please sign in to comment.