1 package Linux
::Proc
::Maps
;
2 # ABSTRACT: Read and write /proc/[pid]/maps files
3 # KEYWORDS: linux proc procfs
8 our $VERSION = '0.001'; # VERSION
11 use Exporter
qw(import);
12 use namespace
::clean
-except
=> [qw(import)];
14 our @EXPORT_OK = qw(read_maps write_maps parse_maps_single_line format_maps_single_line);
18 my %args = @_ == 1 ? (pid
=> $_[0]) : @_;
20 my $file = $args{file
};
22 if (!$file and my $pid = $args{pid
}) {
23 if ($pid =~ /^\d+$/) {
24 require File
::Spec
::Functions
;
25 my $procfs = $args{mnt
} || $ENV{PERL_LINUX_PROC_MAPS_MOUNT
} ||
26 File
::Spec
::Functions
::catdir
(File
::Spec
::Functions
::rootdir
(), 'proc');
27 $file = File
::Spec
::Functions
::catfile
($procfs, $pid, 'maps');
34 $file or croak
'Filename or PID required';
35 open(my $fh, '<:encoding(UTF-8)', $file) or croak
"Open failed ($file): $!";
39 while (my $line = <$fh>) {
42 my $region = parse_maps_single_line
($line);
45 push @regions, $region;
53 my $regions = shift or croak
'Regions required';
56 ref $regions eq 'ARRAY' or croak
'Regions must be an arrayref';
60 for my $region (@$regions) {
61 $out .= format_maps_single_line
($region);
64 # maybe print out the memory regions to a filehandle
66 if (!$fh and my $file = $args{file
}) {
67 open($fh, '>:encoding(UTF-8)', $file) or croak
"Open failed ($file): $!";
69 print $fh $out if $fh;
75 sub parse_maps_single_line
{
76 my $line = shift or croak
'Line from a maps file required';
80 my ($addr1, $addr2, $read, $write, $exec, $shared, $offset, $device, $inode, $pathname) = $line =~ m
{
82 ([[:xdigit
:]]+)-([[:xdigit
:]]+)
83 \s
+ ([r-
])([w-
])([x-
])([sp
])
85 \s
+ ([[:xdigit
:]]+:[[:xdigit
:]]+)
92 no warnings
'portable'; # for hex() on 64-bit perls
95 address_start
=> hex($addr1),
96 address_end
=> hex($addr2),
98 write => 'w' eq $write,
99 execute
=> 'x' eq $exec,
100 shared
=> 's' eq $shared,
101 offset
=> hex($offset),
104 pathname
=> $pathname || '',
109 sub format_maps_single_line
{
110 my $region = shift or croak
'Region required';
112 my @args = @{$region}{qw(address_start address_end read write execute shared offset device inode)};
113 $args[2] = $args[2] ? 'r' : '-';
114 $args[3] = $args[3] ? 'w' : '-';
115 $args[4] = $args[4] ? 'x' : '-';
116 $args[5] = $args[5] ? 's' : 'p';
118 return sprintf("%-72s %s\n", sprintf("%x-%x %s%s%s%s %08x %s %d", @args), $region->{pathname
});
132 Linux::Proc::Maps - Read and write /proc/[pid]/maps files
140 use Linux::Proc::Maps qw(read_maps);
143 my $vm_regions = read_maps(pid => $$);
145 # by pid with explicit procfs mount:
146 my $vm_regions = read_maps(mnt => '/proc', pid => 123);
149 my $vm_regions = read_maps(file => '/proc/456/maps');
153 This module reads and writes F</proc/[pid]/maps> files that contain listed mapped memory regions.
159 Read and parse a maps file, returning an arrayref of regions (each represented as a hashref). See
160 L</parse_maps_single_line> to see the format of the hashrefs.
162 my $regions = read_maps(%args);
170 C<file> - Path to maps file
174 C<pid> - Process ID (one of C<file> or C<pid> is required)
178 C<mnt> - Absolute path where L<proc(5)> is mounted (optional, default: C</proc>)
184 Returns a string with the contents of a maps file from the memory regions passed.
186 my $file_content = write_maps(\@regions, %args);
188 This is the opposite of L</read_maps>.
196 C<fh> - Write maps to this open file handle (optional)
200 C<file> - Open this filepath and write maps to that file (optional)
204 =head2 parse_maps_single_line
206 Parse and return a single line from a maps file into a region represented as a hashref.
208 my $region = parse_maps_single_line($line);
212 # address perms offset dev inode pathname
213 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
218 address_start => 134512640,
219 address_end => 134569984,
227 pathname => '/usr/sbin/gpm',
230 =head2 format_maps_single_line
232 Return a single line for a maps file from a region represented as a hashref.
234 my $line = format_maps_single_line(\%region);
236 This is the opposite of L</parse_maps_single_line>.
240 L<proc(5)> describes the file format.
244 Please report any bugs or feature requests on the bugtracker website
245 L<https://github.com/chazmcgarvey/Linux-Proc-Maps/issues>
247 When submitting a bug or request, please include a test-file or a
248 patch to an existing test-file that illustrates the bug or desired
253 Charles McGarvey <chazmcgarvey@brokenzipper.com>
255 =head1 COPYRIGHT AND LICENSE
257 This software is copyright (c) 2016 by Charles McGarvey.
259 This is free software; you can redistribute it and/or modify it under
260 the same terms as the Perl 5 programming language system itself.