Skip Menu |

This queue is for tickets about the Sys-Mmap-Simple CPAN distribution.

Report information
The Basics
Id: 42443
Status: rejected
Priority: 0/
Queue: Sys-Mmap-Simple

People
Owner: Nobody in particular
Requestors: pepe [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 0.07
Fixed in: (no value)



Subject: The buffer seems to be a copy of the mapped memory
The test program below (which is written for Linux) mmaps a buffer to a file ("/tmp/testfile", can be initialized whith arbitrary content), then the block is exited, although a reference to the buffer is retained. Before the block is exited, the "testfile" appears in /proc/$$/maps (which should show all files that are currently mmapped into the process). After exiting the block, "testfile" does not appear any more in the maps file. However, the buffer can still be accessed, and the md5 sum is still the same, leading to the conclusion that it is only a copy of the mapped data. Interestingly, if we create a second reference to the buffer (the commented line), the "testfile" still appears in maps. After changing the buffer in the last line of the script, the file on disk does not change, which reinforces my theory that the buffer is only a copy. #!/usr/bin/perl use strict; use warnings; use Sys::Mmap::Simple qw(map_handle map_file); use Digest::MD5 qw(md5_hex); my $this = {}; open my $fh, '+<', '/tmp/testfile' or die $!; $this->{buffer} = \do { map_handle(my $buf, $fh, '+<') or die $!; warn md5_hex($buf); warn "first grep:\n"; system("grep testfile /proc/$$/maps >/dev/tty"); warn "----\n"; # $::x = \$buf; $buf; }; warn "second grep:\n"; system("grep testfile /proc/$$/maps >/dev/tty"); warn "----\n"; warn md5_hex ${$this->{buffer}}; substr(${$this->{buffer}}, 0, 1) = 'x'; Now here is the output: shell$ cat /tmp/testfile 123 shell$ perl map.pl ba1f2511fc30423bdbb183fe33f3dd0f at map.pl line 15. first grep: b7fd1000-b7fd2000 rw-s 00000000 00:0f 147712 /tmp/testfile ---- second grep: ---- ba1f2511fc30423bdbb183fe33f3dd0f at map.pl line 26. shell$ cat /tmp/testfile 123 I'd have expected to see "testfile" in the output after "second grep", and I'd have expected that the test file's content would be "x23" after the script run. The test suite runs fine here, however I've noticed that there are no tests that affirm that the file really changes on disk if the mmapped buffer is modified.
If I use a normal my-variable as the buffer and omit that complicated reference setup, the file does change on disk and it does appear in /proc/$$/maps. So I'm sorry to question your module's functionality :) Apparently the problem is that at some point in this passing around of references, the buffer gets copied. This isn't probably an error in your module at all.
On Thu Jan 15 14:09:59 2009, der-pepe wrote: Show quoted text
> If I use a normal my-variable as the buffer and omit that complicated > reference setup, the file does change on disk and it does appear in > /proc/$$/maps. So I'm sorry to question your module's functionality :) > Apparently the problem is that at some point in this passing around of > references, the buffer gets copied. This isn't probably an error in > your module at all.
The bug is in your do block. Your do block returns a copy of $buf, and you take a reference to that. Instead of doing this $foo = \do { ... $buf } You could do this: $foo = do { ... \$buf } Regards, Leon Timmermans P.S. My map functions always throw an exception when an error occurs, there is no need for `or die $!` after them.