4

For debugging purposes I'd like to Access the lexical scope of different subroutines with a specific Attribute set. That works fine. I get a Problem when the first variable stores a string, then I get a empty string. I do something like this:

$pad = $cv->PADLIST; # $cv is the coderef to the sub
@scatchpad = $pad->ARRAY; # getting the scratchpad
@varnames = $scratchpad[0]->ARRAY; # getting the variablenames
@varcontents = $scratchpad[1]->ARRAY; # getting the Content from the vars

for (0 .. $#varnames) {
    eval {
        my $name = $varnames[$_]->PV;
        my $content;
        # following line  matches numbers, works so far
        $content = $varcontent[$_]->IVX if (scalar($varcontent[$_]) =~ /PVIV=/);
        # should match strings, but does give me undef
        $content = B::perlstring($varcontent[$_]->PV) if (scalar($varcontent[$_]) =~ /PV=/);
        print "DEBUGGER> Local variable: ", $name, " = ", $content, "\n";
    }; # there are Special vars that throw a error, but i don't care about them
}

Like I said in the comment the eval is to prevent the Errors from the B::Special objects in the scratchpad. Output:

Local variable: $test = 42
Local variable: $text = 0

The first Output is okay, the second should Output "TEXT" instead of 0.

What am I doing wrong?

EDIT: With a little bit of coding I got all values of the variables , but not stored in the same indexes of @varnames and @varcontents. So now is the question how (in which order) the values are stored in @varcontents.

use strict;
use warnings;
use B;

sub testsub {
    my $testvar1 = 42;
    my $testvar2 = 21;
    my $testvar3 = "testval3";
    print "printtest1";
    my $testvar4 = "testval4";
    print "printtest2";
    return "returnval";
}

no warnings "uninitialized";

my $coderef = \&testsub;
my $cv = B::svref_2object ( $coderef );
my $pad = $cv->PADLIST; # get scratchpad object
my @scratchpad = $pad->ARRAY;
my @varnames = $scratchpad[0]->ARRAY; # get varnames out of scratchpad
my @varcontents = $scratchpad[1]->ARRAY; # get content array out of scratchpad

my @vars; # array to store variable names adn "undef" for special objects (print-values, return-values, etc.)

for (0 .. $#varnames) {
    eval { push @vars, $varnames[$_]->PV; };
    if ($@) { push @vars, "undef"; }
}

my @cont; # array to store the content of the variables and special objects

for (0 .. $#varcontents) {
    eval { push @cont, $varcontents[$_]->IV; };
    eval { push @cont, $varcontents[$_]->PV; };
}

print $vars[$_], "\t\t\t", $cont[$_], "\n" for (0 .. $#cont);

EDIT2: Added runnable script to demonstrate the issue: Variablenames and variablevalues are not stored in the same index of the two Arrays (@varnames and @varcontents).

user2875983
  • 303
  • 2
  • 6
  • 1
    Is there a reason you're using B and manual PADLIST walking, instead of using such modules as `PadWalker` which will do all of this for you? – LeoNerd Jul 28 '14 at 13:18
  • 1
    because PadWalkers "peek_sub" gives all Variablenames but the content-reference given is undef if the sub does not call "peek_sub" at itself as mentioned in the documentation. With B you get the values of the lexical vars also outside of the sub. – user2875983 Jul 28 '14 at 16:34
  • 1
    PadWalker gives undef for those slots when the function isn't being called precisely because those slots are undef. They are assigned to as normal assignment operations; without the function having been called the values are just undef. – LeoNerd Aug 04 '14 at 13:12

0 Answers0