Debugging B::C, hitting the recursion depth

The nature of the data driven perl compiler is hitting the perl debuggers recursion limit, even on one-liners.

Consider this bug: [CPAN #53889]


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

The compiler does not detect the meth sub in the dummy package.

  $ perl -MO=C,-DcOACMSGpo,-v,-oa.c -e 'package dummy;
                 sub meth{print "ok"};package main;dummy->meth'
  $ cc_harness a.c
  $ ./a

Can't locate object method "meth" via package "dummy" (perhaps you forgot to load "dummy"?) at -e line 1.

BTW: Easier tested in the distro with

$ t/testc.sh 35

First if you don't see the error in the generated c file, always turn on all debugging options and save it into a log file.

$ perl -Mblib -MO=C,-DcOACMSGpoW,-v,-occode35.c ccode35.pl 2>&1 | tee methodcall.log

"-DcOACMSGpoW,-v" is all debugging info you get.

Now let's debug it.

$ cpan B::Debugger
$ perl -Mblib -d -MOd=C,-DcOACMSGpo,-v -e 'package dummy;
                                                   sub meth{print "ok"};package main;dummy->meth'
The code in question is in &should_save.
Od::CODE(0x1870d30)((eval 9)[/cygdrive/f/prog/Perl/B-C/blib/lib/Od.pm:12]:11):
11:                 &$compile();
DB<1> s
B::C::CODE(0x1453910)(/cygdrive/f/prog/Perl/B-C/blib/lib/B/C.pm:3295):
3295:       return sub { save_main() };
DB<1> s
B::C::save_main(/cygdrive/f/prog/Perl/B-C/blib/lib/B/C.pm:3005):
3005:     my $warner = $SIG{__WARN__};
DB<1> c should_save

Debugged program terminated. Use q to quit or R to restart,
use o inhibit_exit to avoid stopping after program termination,
h q, h R or h o to get additional info.

Oops. Not stopping there. Od is not perfect yet.
Next attempt with line number.

s 
s 
b 2908

99 levels deep in subroutine calls!

Oops. But this is typcial whith such data-driven code.
We are enhancing the recursion limit (deep) from 100 to 500,


x $DB::deep = 500
c


B::C::should_save(/cygdrive/f/prog/Perl/B-C/blib/lib/B/C.pm:2908):
2908: foreach my $m (qw(new DESTROY TIESCALAR TIEARRAY TIEHASH TIEHANDLE)) {

better attempt.

And now set a conditional breakpoint which only breaks when considering the "dummy" package


b 2908 $package eq 'dummy'
c
x \%unused_sub_packages

and so on. This is pretty deep in the symbol walker, which tries to detect all possible used subs in possible used packages. Undetected packages will cause such errors,

Can't locate object method "meth" via package "dummy" (perhaps you forgot to load "dummy"?) at -e line 1.

Lets continue:


DB<2> n
2915: delete_unsaved_hashINC($package);
DB<2>
2916: return $unused_sub_packages{$package} = 0;
DB<2>
2959: walkpackages( \%{"main::"}, sub { should_save( $_[0] ); return 1 } );
DB<2> s
2942: walkpackages( \%glob, $recurse, $sym );
DB<3> x \%glob
0 HASH(0x14ab450)
'DESTROY' => *dummy::DESTROY
'TIEARRAY' => *dummy::TIEARRAY
'TIEHANDLE' => *dummy::TIEHANDLE
'TIEHASH' => *dummy::TIEHASH
'TIESCALAR' => *dummy::TIESCALAR
'meth' => *dummy::meth
'new' => *dummy::new

Aha, the meth symbol is there. The error is probably somewhere else in the method_named() op.

To be continued at part 2 Debugging B::C, gdb into it.

Leave a comment

About Reini Urban

user-pic Working at cPanel on B::C (the perl-compiler), p2, types, parrot, B::Generate, cygwin perl and more guts (LLVM, jit, optimizations).