(OR) how MAP_FAIL, SIGBUS,
beg to differ with mmap!!
Wrote a small program using mmap() to copy a fromFile.txt to toFile.txt using virtual memory
--------------------------------------------
Issue#1: mmap() returns MAP_FAIL
mmap() requires exactly the same flags as the filedescriptor/fd as when it was open()/creat()-ed
i.e. if you used O_RDONLY in open() then you can't mmap() it as PROT_WRITE.
chmod basics: http://www.linux.org/lessons/beginner/l14/lesson14b.html
creat/open man page: http://linux.about.com/od/commands/l/blcmdl2_open.htm
-------------------------------------------------
Issue#2:
Error Message: In gdb getting SIGBUS with error coming from inside memcpy!!
108 memcpy(destFilePtr, srcFilePtr, pageSize);
5: pageSize = 14
4: destFilePtr = 0xb7ffc000
3: srcFilePtr = 0xb7ffd000 "hello, world\n\n"
2: destfd = 6
1: srcfd = 5
(gdb) n
Program received signal SIGBUS, Bus error.
__memcpy_ia32 () at ../sysdeps/i386/i686/multiarch/../memcpy.S:75
75 ../sysdeps/i386/i686/multiarch/../memcpy.S: No such file or directory.
in ../sysdeps/i386/i686/multiarch/../memcpy.S Searching on this gave no direct answers on the error message but gave some pointers on causes. Tried all the below tools but still getting the same error message:
0) used apt-get update and rebooted "just-in-case" https://help.ubuntu.com/8.04/serverguide/C/apt-get.html 1) used strace ./file-copy-vm to check the system calls were getting called properly. getting SIGBUS on write() ostensibly called from inside the memcpy 2) used ldd ./file-copy-vm to check that the libstdc++ - and libc.so were existent. They were present 3) Installed glibc-dbg and libstdc++-devel etc for debugging the library. No change. Finally found the problem in an off-by-N error in memcpy(dest,src, pageSize)
Since SIGBUS comes when a page worth is allocated but size of mapping is less than pagesize. i.e. the accessed address is more than filesize but inside pagesize.
So realized my mistake and changed: memcpy(destFilePtr, srcFilePtr, pageSize); //WRONG. Corrected it to: memcpy(destFilePtr, srcFilePtr, sb.st_size); //Correct
------------------------------------------------------------------------------------------------------------------
Issue#3: Still getting SIGBUS from memcpy() AND out of bounds>
Breakpoint 3, doFileCopyWithSharedMem (srcFileName=..., destFileName=..., sharedMemSize=8192) at ../src/file-copy-vm.cpp:104
104 cout<< "PID:" << getpid() <
4: destfd = 6
3: srcfd = 5
2: srcFilePtr = 0xb7ffd000 "hello, world\n\n"
1: destFilePtr = 0xb7ffc000
0xb7ffc00 out of bounds>
(gdb) n
PID:7136
106 system("cat /proc/self/maps");
4: destfd = 6
3: srcfd = 5
2: srcFilePtr = 0xb7ffd000 "hello, world\n\n"
1: destFilePtr = 0xb7ffc00 0xb7ffc00 out of bounds>
(gdb) shell cat /proc/7136/maps
[SNIP]
08048000-0804a000 r-xp 00000000 08:01 933913 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/file-copy-vm
0804a000-0804b000 r--p 00001000 08:01 933913 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/file-copy-vm
0804b000-0804c000 rw-p 00002000 08:01 933913 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/file-copy-vm
0804c000-0806d000 rw-p 00000000 00:00 0 [heap]
b7fec000-b7fee000 rw-p 00000000 00:00 0
b7ffb000-b7ffc000 rw-p 00000000 00:00 0
b7ffc000-b7ffd000 rw-s 00000000 08:01 933725 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/toFile.txt
b7ffd000-b7ffe000 r--s 00000000 08:01 933672 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/fromFile.txt
b7ffe000-b8000000 rw-p 00000000 00:00 0
bffeb000-c0000000 rw-p 00000000 00:00 0 [stack]
Hmmm... here the destFilePtr seems to be pointing to the correct memory-mapped file i.e. toFile.txtThe destFilePtr is pointing to out-of-bounds accesss. Also the SIGBUG seems to suggest that I'm trying to write/access to an address in memory that's allocated but out of bounds of the empty dest file. Otherwise I'd have got a SIGSEGV if the memory had not been allocated. I observed that toFile.txt is showing filesize as zero on the disk. Aha!! Robert Love in his book "Linux System Programming" had mentioned files with slack-space/holes (in memory as well as disk respectively). Could this be the reason??!! http://www.devshed.com/c/a/BrainDump/Using-mmap-for-Advanced-File-IO/ Finally I cross-checked my code with a sample implementation for mmap() file copy program. Found out that they used lseek() to expand the memory mapping instead of ftruncate() to expand file size with a hole instead of ftruncate(). http://www.c.happycodings.com/Gnu-Linux/code6.html
So we just need to increase the size of the dest-file using ftruncate.
(gdb) help call
Call a function in the program.
The argument is the function name and arguments, in the notation of the
current working language. The result is printed and saved in the value
history, if it is not void.
(gdb) call ftruncate(destfd,sb.st_size)
$1 = 0
doFileCopyWithSharedMem() returned:0
system(diff ./fromFile.txt ./toFile.txt) returned: 0
testFileCopyWithSharedMem() returned:0
(gdb)
Hurray!! the unit testcase passes!!
It's 6 AM!! Tiring but worth it!! Gotta go and sleep now
----------------------------------------------------------------------------
See Also : mmap is not the territory Part 2 : http://techtalkies.blogspot.in/2010/09/mmap-is-not-territory-part-2.html
beg to differ with mmap!!
Wrote a small program using mmap() to copy a fromFile.txt to toFile.txt using virtual memory
--------------------------------------------
Issue#1: mmap() returns MAP_FAIL
mmap() requires exactly the same flags as the filedescriptor/fd as when it was open()/creat()-ed
i.e. if you used O_RDONLY in open() then you can't mmap() it as PROT_WRITE.
chmod basics: http://www.linux.org/lessons/beginner/l14/lesson14b.html
creat/open man page: http://linux.about.com/od/commands/l/blcmdl2_open.htm
-------------------------------------------------
Issue#2:
Error Message: In gdb getting SIGBUS with error coming from inside memcpy!!
108 memcpy(destFilePtr, srcFilePtr, pageSize);
5: pageSize = 14
4: destFilePtr = 0xb7ffc000
3: srcFilePtr = 0xb7ffd000 "hello, world\n\n"
2: destfd = 6
1: srcfd = 5
(gdb) n
Program received signal SIGBUS, Bus error.
__memcpy_ia32 () at ../sysdeps/i386/i686/multiarch/../memcpy.S:75
75 ../sysdeps/i386/i686/multiarch/../memcpy.S: No such file or directory.
in ../sysdeps/i386/i686/multiarch/../memcpy.S Searching on this gave no direct answers on the error message but gave some pointers on causes. Tried all the below tools but still getting the same error message:
0) used apt-get update and rebooted "just-in-case" https://help.ubuntu.com/8.04/serverguide/C/apt-get.html 1) used strace ./file-copy-vm to check the system calls were getting called properly. getting SIGBUS on write() ostensibly called from inside the memcpy 2) used ldd ./file-copy-vm to check that the libstdc++ - and libc.so were existent. They were present 3) Installed glibc-dbg and libstdc++-devel etc for debugging the library. No change. Finally found the problem in an off-by-N error in memcpy(dest,src, pageSize)
Since SIGBUS comes when a page worth is allocated but size of mapping is less than pagesize. i.e. the accessed address is more than filesize but inside pagesize.
So realized my mistake and changed: memcpy(destFilePtr, srcFilePtr, pageSize); //WRONG. Corrected it to: memcpy(destFilePtr, srcFilePtr, sb.st_size); //Correct
------------------------------------------------------------------------------------------------------------------
Issue#3: Still getting SIGBUS from memcpy() AND out of bounds>
Breakpoint 3, doFileCopyWithSharedMem (srcFileName=..., destFileName=..., sharedMemSize=8192) at ../src/file-copy-vm.cpp:104
104 cout<< "PID:" << getpid() <
4: destfd = 6
3: srcfd = 5
2: srcFilePtr = 0xb7ffd000 "hello, world\n\n"
1: destFilePtr = 0xb7ffc000
(gdb) n
PID:7136
106 system("cat /proc/self/maps");
4: destfd = 6
3: srcfd = 5
2: srcFilePtr = 0xb7ffd000 "hello, world\n\n"
1: destFilePtr = 0xb7ffc00 0xb7ffc00 out of bounds>
(gdb) shell cat /proc/7136/maps
[SNIP]
08048000-0804a000 r-xp 00000000 08:01 933913 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/file-copy-vm
0804a000-0804b000 r--p 00001000 08:01 933913 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/file-copy-vm
0804b000-0804c000 rw-p 00002000 08:01 933913 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/file-copy-vm
0804c000-0806d000 rw-p 00000000 00:00 0 [heap]
b7fec000-b7fee000 rw-p 00000000 00:00 0
b7ffb000-b7ffc000 rw-p 00000000 00:00 0
b7ffc000-b7ffd000 rw-s 00000000 08:01 933725 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/toFile.txt
b7ffd000-b7ffe000 r--s 00000000 08:01 933672 /home/gurud/cdt-linux-tools-workspace/file-copy-vm/Debug/fromFile.txt
b7ffe000-b8000000 rw-p 00000000 00:00 0
bffeb000-c0000000 rw-p 00000000 00:00 0 [stack]
Hmmm... here the destFilePtr seems to be pointing to the correct memory-mapped file i.e. toFile.txtThe destFilePtr is pointing to out-of-bounds accesss. Also the SIGBUG seems to suggest that I'm trying to write/access to an address in memory that's allocated but out of bounds of the empty dest file. Otherwise I'd have got a SIGSEGV if the memory had not been allocated. I observed that toFile.txt is showing filesize as zero on the disk. Aha!! Robert Love in his book "Linux System Programming" had mentioned files with slack-space/holes (in memory as well as disk respectively). Could this be the reason??!! http://www.devshed.com/c/a/BrainDump/Using-mmap-for-Advanced-File-IO/ Finally I cross-checked my code with a sample implementation for mmap() file copy program. Found out that they used lseek() to expand the memory mapping instead of ftruncate() to expand file size with a hole instead of ftruncate(). http://www.c.happycodings.com/Gnu-Linux/code6.html
So we just need to increase the size of the dest-file using ftruncate.
(gdb) help call
Call a function in the program.
The argument is the function name and arguments, in the notation of the
current working language. The result is printed and saved in the value
history, if it is not void.
(gdb) call ftruncate(destfd,sb.st_size)
$1 = 0
doFileCopyWithSharedMem() returned:0
system(diff ./fromFile.txt ./toFile.txt) returned: 0
testFileCopyWithSharedMem() returned:0
(gdb)
Hurray!! the unit testcase passes!!
It's 6 AM!! Tiring but worth it!! Gotta go and sleep now
----------------------------------------------------------------------------
See Also : mmap is not the territory Part 2 : http://techtalkies.blogspot.in/2010/09/mmap-is-not-territory-part-2.html
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.