Debugging B::C, gdb into it (part 2)

At the previous entry Debugging B::C, hitting the recursion depth I showed how attack a typical B::C problem, how to use the perl level debugger
stepping into compiling code with Od.

However we found no error in the compiler at a first glance.
Inspecting the generated c code we see for the perl code

package dummy;sub meth{print "ok"};package main;dummy->meth

parts of the optree as

listop_list[0].op_ppaddr = PL_ppaddr[OP_LEAVE];
op_list[0].op_ppaddr = PL_ppaddr[OP_ENTER];
cop_list[0].op_ppaddr = PL_ppaddr[OP_NEXTSTATE];
cop_list[0].cop_warnings = pWARN_STD;
unop_list[0].op_ppaddr = PL_ppaddr[OP_ENTERSUB];
op_list[1].op_ppaddr = PL_ppaddr[OP_PUSHMARK];
sv_list[0].sv_u.svu_pv = savepvn("dummy", 5);
svop_list[0].op_ppaddr = PL_ppaddr[OP_CONST];
sv_list[1].sv_u.svu_pv = savepvn("meth", 4);
svop_list[1].op_ppaddr = PL_ppaddr[OP_METHOD_NAMED];
..

Check the optree with Concise:


$ perl -MO=Concise -e'package dummy;sub meth{print "ok"};
package main;dummy->meth'

7 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 2 -e:1) v:{ ->3
6 <1> entersub[t1] vKS/TARG ->7
3 <0> pushmark s ->4
4 <$> const[PV "dummy"] sM/BARE ->5
5 <$> method_named[PV "meth"] ->6

Looks correct.

Let's debug into that live. Maybe method_named is wrong.
You need a DEBUGGING perl, and I always prefer -g3 to expand macros.

I generated that as testcase 35 with t/testc.sh 35,
so I get a ccode35.c and exe.

$ gdb ccode35
(gdb) start
main (argc=1, argv=0x1499a60, env=0x14880e0) at ccode35.c:240
240     {
(gdb) b Perl_pp_method_named
Breakpoint 2 at 0x5212b7b9: file pp_hot.c, line 3023.
(gdb) c
Breakpoint 2, Perl_pp_method_named () at pp_hot.c:3023
3023        dVAR; dSP;
(gdb) bt
#0  Perl_pp_method_named () at pp_hot.c:3023
#1  0x520d95d1 in Perl_runops_debug () at dump.c:1968
#2  0x52027747 in S_run_body (oldscope=1) at perl.c:2431
#3  0x52026ce7 in perl_run (my_perl=0x1499b60) at perl.c:2349
#4  0x00401e00 in _fu25__PL_compcv () at ccode35.c:307
(gdb) n
3024        SV* const sv = cSVOP_sv;
(gdb) n
3025        U32 hash = SvSHARED_HASH(sv);
(gdb)
3027        XPUSHs(method_common(sv, &hash));
(gdb) p *sv
$1 = {sv_any = 0x403390, sv_refcnt = 1, sv_flags = 151012357, sv_u = {
    svu_iv = 21808872, svu_uv = 21808872, svu_rv = 0x14cc6e8,
    svu_pv = 0x14cc6e8 "meth", svu_array = 0x14cc6e8, svu_hash = 0x14cc6e8,
    svu_gp = 0x14cc6e8}}
(gdb) x Perl_sv_dump(sv)
SV = PV(0x403390) at 0x403158
  REFCNT = 1
  FLAGS = (POK,FAKE,READONLY,pPOK)
  PV = 0x14cc6e8 "meth"\0
  CUR = 4
  LEN = 5
Value can't be converted to integer.
(gdb) n
Can't locate object method "meth" via package "dummy" (perhaps you forgot to load "dummy"?) at ccode35 line 1.

So we are in the method named "meth", which should be in the "dummy" package.
Since the error is
Can't locate object method "meth" via package "dummy".
we believe that the cv optree for &dummy::meth is not stored.

Indeed inspecting the c code shows us:


svop_list[1].op_ppaddr = PL_ppaddr[OP_METHOD_NAMED];

/* done main optree, extra subs which might be unused */
/* done extras */

There's only the optree for main, but no further extra subs.
We miss the ops for &dummy::meth. There must be a print with const "ok"

Back to the B::Debugger Od.
Why is this sub not stored?

To be continued in the workaround (part 3)

About Reini Urban

user-pic Working at cPanel on cperl, B::C (the perl-compiler), parrot, B::Generate, cygwin perl and more guts, keeping the system alive.