Skip to content

Commit bce5eba

Browse files
committed
Improve 'perl -Dx' debug output on threaded builds
A couple of commits ago I added a mechanism to display the values of the SV for ops (such as OP_CONST and OP_GVSV) on threaded builds when possible, where the SV has been moved into the pad. This commit extends that mechanism to work when a sub's optree is being dumped via the '-Dx' perl command-line switch. That previous commit tried to find the CV (and thus pad) associated with the op being dumped by rummaging around on the context and parse stacks. But the -Dx mechanism is neither of those things. It dumps all the subs it can find in packages after compilation, but before execution. This commit adds an extra parameter to S_do_op_dump_bar() which optionally indicates what CV is having its optree dumped. The -Dx mechanism can use this parameter to pass a hint to the SV-in-pad finding code. If the parameter is null, it falls back to the mechanisms added in the previous commits.
1 parent 6d38f15 commit bce5eba

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

dump.c

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,8 @@ Perl_dump_sub(pTHX_ const GV *gv)
876876

877877
/* forward decl */
878878
static void
879-
S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o);
879+
S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o,
880+
CV* rootcv);
880881

881882

882883
void
@@ -907,7 +908,7 @@ Perl_dump_sub_perl(pTHX_ const GV *gv, bool justperl)
907908
PTR2UV(CvXSUB(cv)),
908909
(int)CvXSUBANY(cv).any_i32);
909910
else if (CvROOT(cv))
910-
S_do_op_dump_bar(aTHX_ 0, 0, Perl_debug_log, CvROOT(cv));
911+
S_do_op_dump_bar(aTHX_ 0, 0, Perl_debug_log, CvROOT(cv), cv);
911912
else
912913
Perl_dump_indent(aTHX_ 0, Perl_debug_log, "<undef>\n");
913914
}
@@ -973,7 +974,8 @@ S_gv_display(pTHX_ GV *gv)
973974

974975

975976
static void
976-
S_do_pmop_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const PMOP *pm)
977+
S_do_pmop_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const PMOP *pm,
978+
CV* rootcv)
977979
{
978980
UV kidbar;
979981

@@ -1013,7 +1015,7 @@ S_do_pmop_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const PMOP *pm)
10131015
S_opdump_indent(aTHX_ (OP*)pm, level, bar, file, "PMf_REPL =\n");
10141016
S_do_op_dump_bar(aTHX_ level + 2,
10151017
(kidbar|cBOOL(OpHAS_SIBLING(pm->op_pmreplrootu.op_pmreplroot))),
1016-
file, pm->op_pmreplrootu.op_pmreplroot);
1018+
file, pm->op_pmreplrootu.op_pmreplroot, rootcv);
10171019
}
10181020
}
10191021

@@ -1022,7 +1024,7 @@ S_do_pmop_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const PMOP *pm)
10221024
S_opdump_indent(aTHX_ (OP*)pm, level, bar, file, "CODE_LIST =\n");
10231025
S_do_op_dump_bar(aTHX_ level + 2,
10241026
(kidbar | cBOOL(OpHAS_SIBLING(pm->op_code_list))),
1025-
file, pm->op_code_list);
1027+
file, pm->op_code_list, rootcv);
10261028
}
10271029
else
10281030
S_opdump_indent(aTHX_ (OP*)pm, level, bar, file,
@@ -1035,7 +1037,7 @@ void
10351037
Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm)
10361038
{
10371039
PERL_ARGS_ASSERT_DO_PMOP_DUMP;
1038-
S_do_pmop_dump_bar(aTHX_ level, 0, file, pm);
1040+
S_do_pmop_dump_bar(aTHX_ level, 0, file, pm, NULL);
10391041
}
10401042

10411043

@@ -1107,13 +1109,16 @@ S_pm_description(pTHX_ const PMOP *pm)
11071109
*
11081110
* Return NULL if it can't be found.
11091111
*
1112+
* Sometimes the caller *does* know what CV is being dumped; if so, it
1113+
* is passed as rootcv.
1114+
*
11101115
* Since this may be called during debugging and things may not be in a
11111116
* sane state, be conservative, and if in doubt, return NULL.
11121117
*/
11131118

11141119
#ifdef USE_ITHREADS
11151120
static SV *
1116-
S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po)
1121+
S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po, CV *rootcv)
11171122
{
11181123
PADLIST *padlist; /* declare early to work round compiler quirks */
11191124

@@ -1122,6 +1127,11 @@ S_get_sv_from_pad(pTHX_ const OP *o, PADOFFSET po)
11221127

11231128
CV *cv = NULL;
11241129

1130+
if (rootcv) {
1131+
cv = rootcv;
1132+
goto got_cv;
1133+
}
1134+
11251135
/* Find the root of the optree this op is embedded in. For a compiled
11261136
* sub, this root will typically be a leavesub or similar attached to
11271137
* a CV. If compiling, this may be a small subtree on the parser
@@ -1296,10 +1306,14 @@ const char * const op_class_names[] = {
12961306
* For heavily nested output, the level may exceed the number of bits
12971307
* in bar; in this case the first few columns in the output will simply
12981308
* not have a bar, which is harmless.
1309+
*
1310+
* rootcv is the CV (if any) whose CvROOT() is the root of the optree
1311+
* currently being dumped.
12991312
*/
13001313

13011314
static void
1302-
S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
1315+
S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o,
1316+
CV* rootcv)
13031317
{
13041318
const OPCODE optype = o->op_type;
13051319

@@ -1469,7 +1483,7 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
14691483
#ifdef USE_ITHREADS
14701484
S_opdump_indent(aTHX_ o, level, bar, file,
14711485
"PADIX = %" IVdf "\n", (IV)cPADOPo->op_padix);
1472-
gv = (GV*)S_get_sv_from_pad(aTHX_ o, cPADOPx(o)->op_padix);
1486+
gv = (GV*)S_get_sv_from_pad(aTHX_ o, cPADOPx(o)->op_padix, rootcv);
14731487
#else
14741488
gv = (GV*)cSVOPx(o)->op_sv;
14751489
#endif
@@ -1518,7 +1532,7 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
15181532
S_opdump_indent(aTHX_ o, level, bar, file,
15191533
"OP_SV = 0x0\n");
15201534
#ifdef USE_ITHREADS
1521-
sv = S_get_sv_from_pad(aTHX_ o, o->op_targ);
1535+
sv = S_get_sv_from_pad(aTHX_ o, o->op_targ, rootcv);
15221536
#endif
15231537
}
15241538

@@ -1545,7 +1559,7 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
15451559
S_opdump_indent(aTHX_ o, level, bar, file,
15461560
"OP_METH_SV = 0x0\n");
15471561
#ifdef USE_ITHREADS
1548-
sv = S_get_sv_from_pad(aTHX_ o, o->op_targ);
1562+
sv = S_get_sv_from_pad(aTHX_ o, o->op_targ, rootcv);
15491563
#endif
15501564
}
15511565

@@ -1561,7 +1575,8 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
15611575
#ifdef USE_ITHREADS
15621576
S_opdump_indent(aTHX_ o, level, bar, file,
15631577
"RCLASS_TARG = %" IVdf "\n", (IV)cMETHOPo->op_rclass_targ);
1564-
sv = S_get_sv_from_pad(aTHX_ o, cMETHOPo->op_rclass_targ);
1578+
sv = S_get_sv_from_pad(aTHX_ o, cMETHOPo->op_rclass_targ,
1579+
rootcv);
15651580
#else
15661581
sv = cMETHOPo->op_rclass_sv;
15671582
#endif
@@ -1651,7 +1666,7 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
16511666
case OP_MATCH:
16521667
case OP_QR:
16531668
case OP_SUBST:
1654-
S_do_pmop_dump_bar(aTHX_ level, bar, file, cPMOPo);
1669+
S_do_pmop_dump_bar(aTHX_ level, bar, file, cPMOPo, rootcv);
16551670
break;
16561671
case OP_LEAVE:
16571672
case OP_LEAVEEVAL:
@@ -1788,15 +1803,15 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
17881803
for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid))
17891804
S_do_op_dump_bar(aTHX_ level,
17901805
(bar | cBOOL(OpHAS_SIBLING(kid))),
1791-
file, kid);
1806+
file, kid, rootcv);
17921807
}
17931808
}
17941809

17951810

17961811
void
17971812
Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o)
17981813
{
1799-
S_do_op_dump_bar(aTHX_ level, 0, file, o);
1814+
S_do_op_dump_bar(aTHX_ level, 0, file, o, NULL);
18001815
}
18011816

18021817

ext/Devel-Peek/t/Peek.t

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,10 +1607,11 @@ dumpindent is 4 at -e line 1.
16071607
|
16081608
7 +--gv SVOP(0xNNN) ===> 5 [entersub 0xNNN]
16091609
FLAGS = (SCALAR,SLABBED)
1610-
GV_OR_PADIX
1610+
OPT_PADIX
1611+
GV = t::DumpProg (0xNNN)
16111612
EODUMP
16121613

1613-
$e =~ s/GV_OR_PADIX/$threads ? "PADIX = 2" : "GV = t::DumpProg (0xNNN)"/e;
1614+
$e =~ s/^(\s+)OPT_PADIX\n/$threads ? "${1}PADIX = 2\n" : ""/me;
16141615
$e =~ s/SVOP/PADOP/g if $threads;
16151616
my $out = t::runperl
16161617
switches => ['-Ilib'],

0 commit comments

Comments
 (0)