File Coverage

blib/lib/Sys/Ptrace.pm
Criterion Covered Total %
statement 30 36 83.3
branch 4 12 33.3
condition 9 15 60.0
subroutine 7 7 100.0
pod 0 1 0.0
total 50 71 70.4


line stmt bran cond sub pod time code
1             package Sys::Ptrace;
2              
3 4     4   99643 use strict;
  4         10  
  4         159  
4 4     4   19 use vars qw( @ISA @EXPORT @EXPORT_OK $VERSION $AUTOLOAD );
  4         7  
  4         328  
5 4     4   22 use Exporter;
  4         12  
  4         153  
6 4     4   123 use DynaLoader;
  4         8  
  4         132  
7 4     4   17 use Carp qw( croak );
  4         6  
  4         2189  
8              
9             $VERSION = '0.06';
10             @ISA = qw(Exporter DynaLoader);
11              
12             @EXPORT_OK = qw(
13             ptrace
14             PT_ATTACH
15             PT_CONTINUE
16             PT_DETACH
17             PT_GETFPREGS
18             PT_GETFPXREGS
19             PT_GETREGS
20             PT_KILL
21             PT_READ_D
22             PT_READ_I
23             PT_READ_U
24             PT_SETFPREGS
25             PT_SETFPXREGS
26             PT_SETREGS
27             PT_STEP
28             PT_SYSCALL
29             PT_TRACE_ME
30             PT_WRITE_D
31             PT_WRITE_I
32             PT_WRITE_U
33             );
34              
35             @EXPORT = qw( ptrace );
36              
37             # THE FOLLOWING HASHREF WAS GENERATED BY:
38             # perl -n -e 'print "$2 => '"'"'$1'"'"',\n" if /define\s+(PT_\w+)\s+(PTRACE_\w+)/;' /usr/include/sys/ptrace.h
39             my $PTRACE_CONSTANT = {
40             PTRACE_TRACEME => 'PT_TRACE_ME',
41             PTRACE_PEEKTEXT => 'PT_READ_I',
42             PTRACE_PEEKDATA => 'PT_READ_D',
43             PTRACE_PEEKUSER => 'PT_READ_U',
44             PTRACE_POKETEXT => 'PT_WRITE_I',
45             PTRACE_POKEDATA => 'PT_WRITE_D',
46             PTRACE_POKEUSER => 'PT_WRITE_U',
47             PTRACE_CONT => 'PT_CONTINUE',
48             PTRACE_KILL => 'PT_KILL',
49             PTRACE_SINGLESTEP => 'PT_STEP',
50             PTRACE_GETREGS => 'PT_GETREGS',
51             PTRACE_SETREGS => 'PT_SETREGS',
52             PTRACE_GETFPREGS => 'PT_GETFPREGS',
53             PTRACE_SETFPREGS => 'PT_SETFPREGS',
54             PTRACE_ATTACH => 'PT_ATTACH',
55             PTRACE_DETACH => 'PT_DETACH',
56             PTRACE_GETFPXREGS => 'PT_GETFPXREGS',
57             PTRACE_SETFPXREGS => 'PT_SETFPXREGS',
58             PTRACE_SYSCALL => 'PT_SYSCALL',
59             };
60              
61             # Allow export for all of them
62             foreach ( keys %{$PTRACE_CONSTANT} ) {
63             push @EXPORT_OK, $_;
64             }
65              
66             foreach (@EXPORT_OK) {
67              
68             # Prototype constants to prepare
69             # for correct entry into the AUTOLOAD
70             eval "sub $_ ();" if /^PT(RACE)?_/;
71             }
72              
73             sub AUTOLOAD {
74              
75             # This AUTOLOAD is used to 'autoload' constants from the constant()
76             # XS function. If a constant is not found then control is passed
77             # to the AUTOLOAD in AutoLoader.
78              
79 46     46   361691 my $constname;
80 46         571 ( $constname = $AUTOLOAD ) =~ s/.*:://;
81 46 50       229 croak "& not defined" if $constname eq 'constant';
82 46   66     523 my $function_name = $PTRACE_CONSTANT->{$constname} || $constname;
83 46 50       433 my $val = constant( $function_name, @_ ? $_[0] : 0 );
84 46 50       749 if ( $! != 0 ) {
85 0         0 croak "Your vendor has not defined Sys::Ptrace macro $constname";
86             }
87 46         4270 eval "sub $constname () { $val; }";
88 46         11449 goto &$AUTOLOAD;
89             }
90              
91             bootstrap Sys::Ptrace $VERSION;
92              
93             # Preloaded methods go here.
94              
95             # Dumb wrapper function to call the internal ptrace C function.
96             # Returns true on success and sets $! on failure.
97             sub ptrace {
98 2     2 0 6 my ( $request, $pid, $addr, $data ) = @_;
99 2   100     31 $pid ||= 0;
100 2   100     14 $addr ||= 0;
101 2   50     22 $data ||= 0;
102 2         66 my $result = _ptrace( $request, $pid, $addr, $data );
103 2 50 33     17 if ( $request == PT_READ_I()
      33        
104             || $request == PT_READ_D()
105             || $request == PT_READ_U() ) {
106 0 0       0 if ( ref $data eq "SCALAR" ) {
    0          
107 0         0 $$data = $result;
108             }
109             elsif ( @_ > 3 ) {
110 0         0 $_[3] = $result;
111             }
112             else {
113 0         0 croak 'PTRACE_PEEK* requires $data to store into';
114             }
115 0         0 $result = 0;
116             }
117 2         30 return !$result;
118             }
119              
120             1;
121             __END__