* mmap causing bus error
@ 2023-11-08 20:21 Levo D
0 siblings, 0 replies; only message in thread
From: Levo D @ 2023-11-08 20:21 UTC (permalink / raw)
To: linux-api
[-- Attachment #1: Type: text/plain, Size: 703 bytes --]
When I mmap a file it's possible to have a bus error and I attached some code to reproduce it
The reproduce steps are in main.c. I choose to use mmap because I noticed doing an `read` on a large file is a bit slow. It seems like the kernel will zero out everything then write the file contents to the buffer. mmap is significantly faster but risk corrupting data and having a bus error (also doesn't seem like zero copy).
Essentially what the program is is write to the contents of the file while main.c is using it which causes bad data OR it will TRUNC the file and cause a bus error + coredump. Are there ways to get a copy without being as 'slow' as `read` and doesn't have the downsides of mmap?
[-- Attachment #2: main.c --]
[-- Type: application/octet-stream, Size: 1508 bytes --]
/* Reproducable steps
gcc -g main.c -o app1
gcc -g app2.c -o app2
fn=/tmp/uB2kCDFlDoRA56gdeuvOVKbL1KHXxMhDXc3pFnhjbhc
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 1 | ./app2 $fn
You'll see "Result was 72" instead of "Result was 0"
(app 2 modifies $fn so we'll need dd again)
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 0 | ./app2 $fn
You'll see the desired "Result was 0"
In app2.c uncomment/comment line 13 and 12
gcc app2.c -o app2
Now this will have a bus error and "Result" line will not print
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 1 | ./app2 $fn
read is unaffected
dd if=/dev/zero of=$fn count=5120 bs=4096; ./app1 $fn 0 | ./app2 $fn
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
//a.out filename 1
if (argc != 3) {
fprintf(stderr, "Bad args\n");
return 1;
}
int fd = open(argv[1], O_RDONLY);
struct stat s={0};
fstat(fd, &s);
char*p;
if (argv[2][0] == '1')
p = (char*)mmap(0, s.st_size, PROT_READ , MAP_PRIVATE, fd, 0);
else {
p = (char*)malloc(s.st_size);
read(fd, p, s.st_size);
}
write(2, "Sleeping\n", 9);
write(1, "Sleeping\n", 9); //Triggers the other app to write
sleep(1);
write(2, "Waking\n", 7);
//read first byte of every 4k page
int sum = 0;
for (long i=0; i<s.st_size; i+=4096) {
if (p[i] != 0) {
int z=0;
}
sum += p[i];
}
fprintf(stderr, "Result was %d\n", sum);
return 0;
}
[-- Attachment #3: app2.c --]
[-- Type: application/octet-stream, Size: 401 bytes --]
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "Bad args\n");
return 1;
}
char buf[4096];
read(0, buf, 4096);
int fd = open(argv[1], O_WRONLY|O_CREAT);
//int fd = open(argv[1], O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC); //<-- This one causes a bus error
write(fd, "Hello", 5);
fprintf(stderr, "Written %d\n", fd);
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-11-08 20:21 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-08 20:21 mmap causing bus error Levo D
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).