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 #22602
  • Loading branch information
tonycoz committed Sep 19, 2024
1 parent 55a059e commit 65d14c5
Show file tree
Hide file tree
Showing 7 changed files with 49 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
9 changes: 9 additions & 0 deletions op.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,15 @@ Deprecated. Use C<GIMME_V> instead.
op_convert_list to set op_folded. */
#define OPf_FOLDED (1<<16)

/* In debugging mode newSTATEOP() normally makes an OP_DBSTATE, set
this to force creation of an OP_NEXTSTATE (which isn't
steppable/breakable) instead.
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 65d14c5

Please sign in to comment.