1 package Linux
::Proc
::Maps
;
2 # ABSTRACT: Read and write /proc/[pid]/maps files
3 # KEYWORDS: linux proc procfs
9 our $VERSION = '999.999'; # VERSION
12 use Exporter
qw(import);
13 use namespace
::clean
-except
=> [qw(import)];
15 our @EXPORT_OK = qw(read_maps write_maps parse_maps_single_line format_maps_single_line);
19 use Linux::Proc::Maps qw(read_maps);
22 my $vm_regions = read_maps(pid => $$);
24 # by pid with explicit procfs mount:
25 my $vm_regions = read_maps(mnt => '/proc', pid => 123);
28 my $vm_regions = read_maps(file => '/proc/456/maps');
32 This module reads and writes F</proc/[pid]/maps> files that contain listed mapped memory regions.
36 Read and parse a maps file, returning an arrayref of regions (each represented as a hashref). See
37 L</parse_maps_single_line> to see the format of the hashrefs.
39 my $regions = read_maps(%args);
44 * C<file> - Path to maps file
45 * C<pid> - Process ID (one of C<file> or C<pid> is required)
46 * C<mnt> - Absolute path where L<proc(5)> is mounted (optional, default: C</proc>)
51 my %args = @_ == 1 ? (pid
=> $_[0]) : @_;
53 my $file = $args{file
};
55 if (!$file and my $pid = $args{pid
}) {
56 if ($pid =~ /^\d+$/) {
57 require File
::Spec
::Functions
;
58 my $procfs = $args{mnt
} || $ENV{PERL_LINUX_PROC_MAPS_MOUNT
} ||
59 File
::Spec
::Functions
::catdir
(File
::Spec
::Functions
::rootdir
(), 'proc');
60 $file = File
::Spec
::Functions
::catfile
($procfs, $pid, 'maps');
67 $file or croak
'Filename or PID required';
68 open(my $fh, '<:encoding(UTF-8)', $file) or croak
"Open failed ($file): $!";
72 while (my $line = <$fh>) {
75 my $region = parse_maps_single_line
($line);
78 push @regions, $region;
86 Returns a string with the contents of a maps file from the memory regions passed
.
88 my $file_content = write_maps
(\
@regions, %args);
90 This
is the opposite of L
</read_maps
>.
95 * C<fh> - Write maps to this open file handle (optional)
96 * C<file> - Open this filepath and write maps to that file (optional)
101 my $regions = shift or croak
'Regions required';
104 ref $regions eq 'ARRAY' or croak
'Regions must be an arrayref';
108 for my $region (@$regions) {
109 $out .= format_maps_single_line
($region);
112 # maybe print out the memory regions to a filehandle
114 if (!$fh and my $file = $args{file
}) {
115 open($fh, '>:encoding(UTF-8)', $file) or croak
"Open failed ($file): $!";
117 print $fh $out if $fh;
122 =func parse_maps_single_line
124 Parse
and return a single line from a maps file into a region represented as a hashref
.
126 my $region = parse_maps_single_line
($line);
130 # address perms offset dev inode pathname
131 08048000-08056000 r-xp
00000000 03:0c
64593 /usr/sbin
/gpm
136 address_start
=> 134512640,
137 address_end
=> 134569984,
145 pathname
=> '/usr/sbin/gpm',
150 sub parse_maps_single_line
{
151 my $line = shift or croak
'Line from a maps file required';
155 my ($addr1, $addr2, $read, $write, $exec, $shared, $offset, $device, $inode, $pathname) = $line =~ m
{
157 ([[:xdigit
:]]+)-([[:xdigit
:]]+)
158 \s
+ ([r-
])([w-
])([x-
])([sp
])
160 \s
+ ([[:xdigit
:]]+:[[:xdigit
:]]+)
167 no warnings
'portable'; # for hex() on 64-bit perls
170 address_start
=> hex($addr1),
171 address_end
=> hex($addr2),
172 read => 'r' eq $read,
173 write => 'w' eq $write,
174 execute
=> 'x' eq $exec,
175 shared
=> 's' eq $shared,
176 offset
=> hex($offset),
179 pathname
=> $pathname || '',
183 =func format_maps_single_line
185 Return a single line
for a maps file from a region represented as a hashref
.
187 my $line = format_maps_single_line
(\
%region);
189 This
is the opposite of L
</parse_maps_single_line
>.
193 sub format_maps_single_line
{
194 my $region = shift or croak
'Region required';
196 my @args = @{$region}{qw(address_start address_end read write execute shared offset device inode)};
197 $args[2] = $args[2] ? 'r' : '-';
198 $args[3] = $args[3] ? 'w' : '-';
199 $args[4] = $args[4] ? 'x' : '-';
200 $args[5] = $args[5] ? 's' : 'p';
202 return sprintf("%-72s %s\n", sprintf("%x-%x %s%s%s%s %08x %s %d", @args), $region->{pathname
});
207 L<proc(5)> describes the file format.