How can I convert the stringified version of array reference to actual array reference in Perl?

前端 未结 6 564
南笙
南笙 2020-11-29 11:11

Is there any way to get Perl to convert the stringified version e.g (ARRAY(0x8152c28)) of an array reference to the actual array reference?

For example



        
6条回答
  •  旧巷少年郎
    2020-11-29 11:49

    In case someone finds this useful, I'm extending tobyink's answer by adding support for detecting segmentation faults. There are two approaches I discovered. The first way locally replaces $SIG{SEGV} and $SIG{BUS} before dereferencing. The second way masks the child signal and checks if a forked child can dereference successfully. The first way is significantly faster than the second.

    Anyone is welcome to improve this answer.

    First Approach

    sub unstringify_ref($) {
      use bigint qw(hex);
      use Devel::FindRef;
    
      my $str = @_ ? shift : $_;
      if (defined $str and $str =~ /\((0x[a-fA-F0-9]+)\)$/) {
        my $addr = (hex $1)->bstr;
    
        local $@;
        return eval {
          local $SIG{SEGV} = sub { die };
          local $SIG{BUS} = sub { die };
          return Devel::FindRef::ptr2ref $addr;
        };
      }
      return undef;
    }
    

    I'm not sure if any other signals can occur in an attempt to access illegal memory.

    Second Approach

    sub unstringify_ref($) {
      use bigint qw(hex);
      use Devel::FindRef;
      use Signal::Mask;
    
      my $str = @_ ? shift : $_;
      if (defined $str and $str =~ /\((0x[a-fA-F0-9]+)\)$/) {
        my $addr = (hex $1)->bstr;
    
        local $!;
        local $?;
        local $Signal::Mask{CHLD} = 1;
        if (defined(my $kid = fork)) {
          # Child -- This might seg fault on invalid address.
          exit(not Devel::FindRef::ptr2ref $addr) unless $kid;
          # Parent
          waitpid $kid, 0;
          return Devel::FindRef::ptr2ref $addr if $? == 0;
        } else {
          warn 'Unable to fork: $!';
        }
      }
      return undef;
    }
    

    I'm not sure if the return value of waitpid needs to be checked.

提交回复
热议问题