I am currently writing a program to calculate the Lucas Series, Hexagonal Series, and Harmonic Series given a number from an input file. I am using a pipe and shared memory segment to share values across the programs.
I start by creating my pipe
int p[2];
if (pipe(p) < 0)
fprintf(stderr, "Problem opening pipe!\n");
Then I run a child process to read the contents of the input file into my pipe where argv[1] is the name of the input file(maxPrime is used later but not here)
char tmpbuf[10];
char str[10];
sprintf(tmpbuf, "%d", p[1]);
pid = fork();
int maxPrime;
if (pid < 0) fprintf(stderr, "Error running child process\n");
else if (pid == 0) { // child
close(p[0]);
execlp("./Reader", "reader", argv[1], tmpbuf, NULL);
} else {
wait(&status);
close(p[1]);
read(p[0], str, 10);
printf("[Starter][%ld]: contents read from the read end pipe: %d\n", (long)prPid, atoi(str));
n = atoi(str);
}
And finally, here is where I get the Bus error when trying to access a void pointer array called voidarr. This part of the program is where I am forking to the child processes to get the sums of the numbers in their respective series and print them to the standard output.
shms is an array of ints for file descriptors, voidarr is an array of void * for pointing to the shared memory, and pidArray is for storing the process ID of each child process
char *my_array[3] = {"lucas", "hexagonalseries", "harmonicseries"};
char *my_array2[3] = {"./lucas", "./hexagonalseries", "./harmonicseries"};
char *my_array3[3] = {"SHM_lucas", "SHM_hexagonalseries", "SHM_harmonicseries"};
char *my_array4[3] = {"Lucas.c", "Hexagonalseries.c", "Harmonicseries.c"};
for (int i = 0; i < 3; i ) {
if ((shms[i] = shm_open(my_array3[i], O_CREAT | O_RDWR, 0666)) == -1) {
fprintf(stderr, "Failed to open file descriptor!\n");
return 1;
}
if ((voidarr[i] = mmap(NULL, 32, PROT_WRITE, MAP_SHARED, shms[i], 0)) == MAP_FAILED){
fprintf(stderr, "Failed to map!\n");
return 1;
}
pidArray[i] = fork();
if (pidArray[i] < 0) {
fprintf(stderr, "Error running child process %s", my_array[i]);
} else if (pidArray[i] == 0) {
execlp(my_array2[i], my_array4[i], my_array3[i], (char *) voidarr[i], NULL);
} else { // parent
//RECEIVING BUS ERROR ON LINE BELOW
printf("[Starter]: %d and %s]\n", prPid, (char *)voidarr[i]);
shm_unlink(my_array3[i]);
}
}
This is what my output is
[Starter][1106394] : Created Shared memory "SHM_lucas" with FD: 3
[Starter][1106394] : Created Shared memory "SHM_hexagonalseries"
with FD: 5
[Starter][1106394] : Created Shared memory "SHM_harmonicseries"
with FD: 6
[Starter][1106394]: contents read from the read end pipe: 0
Bus error (core dumped)
Additionally, I don't know if this is needed to answer this question but here is my Reader.c
int main (int argc, char *argv[]) {
if (argc != 3) fprintf(stderr, "[Reader]: Wrong number of arguments, usage requires 2, found %d", argc - 1);
int pipe_ref = atoi(argv[2]);
FILE *f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "File failed to open");
return 1;
}
char buf[256];
int run_sum = 0;
int tmp = 0;
printf("Hello from reader");
while (fgets(buf, sizeof(buf), f)) {
tmp = atoi(buf);
run_sum = tmp;
}
sprintf(buf, "%d", run_sum);
write (pipe_ref, buf, sizeof(buf));
return 0;
}
CodePudding user response:
Your problem is that after doing shm_open
, doing fstat
on the return value shows an st_size
value of 0!
Initially, the descriptor from shm_open
has zero size. It must be explicitly given a size. Note that just specifying 32 as a length to mmap
does not cause the file to be expanded.
This must be done with ftruncate
.
After the shm_open
call, you need to do:
ftruncate(shms[i],32);
Here is a patch against your github repo. Even without that, it shows the changes needed:
diff --git a/Makefile b/Makefile
index 9ea673f..a478bf6 100644
--- a/Makefile
b/Makefile
@@ -1,29 1,38 @@
CC=gcc
CFLAGS=-Wall -lrt
CFLAGS = -g
-build: Starter HarmonicSeries HexagonalSeries Lucas Reader
TARGETS = Starter HarmonicSeries HexagonalSeries Lucas Reader
build: $(TARGETS)
Starter: Starter.c
- $(CC) -o Starter $(CFLAGS) Starter.c
$(CC) -o $@ $(CFLAGS) Starter.c
HarmonicSeries: HarmonicSeries.c
- $(CC) -o harmonicseries $(CFLAGS) HarmonicSeries.c
$(CC) -o $@ $(CFLAGS) HarmonicSeries.c
HexagonalSeries: HexagonalSeries.c
- $(CC) -o hexagonalseries $(CFLAGS) HexagonalSeries.c
$(CC) -o $@ $(CFLAGS) HexagonalSeries.c
Lucas: Lucas.c
- $(CC) -o lucas $(CFLAGS) Lucas.c
$(CC) -o $@ $(CFLAGS) Lucas.c
Reader: Reader.c
- $(CC) -o reader $(CFLAGS) Reader.c
$(CC) -o $@ $(CFLAGS) Reader.c
clean:
- rm -rf *.o Starter HarmonicSeries HexagonalSeries Lucas
rm -rf *.o $(TARGETS) gdbcmds
test:
./Starter file_01.in
gdb: gdbcmds
gdb -x gdbcmds ./Starter
gdbcmds:
echo "set args file_01.in" > $@
tar:
tar -cvzf Anon-HW3.tar Starter.c Lucas.c HexagonalSeries.c HarmonicSeries.c Makefile README.txt
diff --git a/Starter.c b/Starter.c
index 31feae5..6ebfc35 100644
--- a/Starter.c
b/Starter.c
@@ -6,6 6,7 @@
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/shm.h>
#include <sys/stat.h>
//for testing
#include <inttypes.h>
@@ -38,7 39,7 @@ int main(int argc, char *argv[]) {
n = atoi(str);
}
for (int i = 0; i < n; i ) {
- for (int j = 0; j < i/2; j ) {
for (int j = 1; j < i/2; j ) {
if (i % j == 0) continue;
if (j == i/2-1) {
maxPrime = i;
@@ -63,7 64,45 @@ int main(int argc, char *argv[]) {
for (int i = 0; i < 3; i ) {
shms[i] = shm_open(my_array3[i], O_CREAT | O_RDWR, 0666);
#if 1
if (shms[i] < 0) {
perror("shm_open");
exit(1);
}
#endif
#if 1
struct stat st;
fstat(shms[i],&st);
printf("DEBUG i=%d st_size=%zu\n",i,st.st_size);
#endif
// NOTE/FIX: at this point, st_size is zero!
// need to provide some space
#if 1
ftruncate(shms[i],32);
fstat(shms[i],&st);
printf("DEBUG i=%d st_size=%zu\n",i,st.st_size);
#endif
#if 0
voidarr[i] = mmap(NULL, 32, PROT_WRITE, MAP_SHARED, shms[i], 0);
#else
voidarr[i] = mmap(NULL, 32, PROT_READ | PROT_WRITE, MAP_SHARED, shms[i], 0);
if (voidarr[i] == MAP_FAILED) {
perror("mmap");
exit(1);
}
#endif
printf("DEBUG: i=%d shms=%d voidarr=%p my_array3='%s'\n",
i,shms[i],voidarr[i],my_array3[i]);
// NOTE/BUG: this produces SIGBUS!!!
int probe = *(char *) voidarr[i];
printf("DEBUG/PROBE: probe=%d\n",probe);
pidArray[i] = fork();
if (pidArray[i] < 0) {
fprintf(stderr, "Error running child process %s", my_array[i]);
Here is the output of the modified program:
./Starter file_01.in
Hello from reader[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=1 st_size=0
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=2 st_size=0
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
DEBUG i=1 st_size=32
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=2 st_size=32
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=1 st_size=0
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
DEBUG i=2 st_size=32
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
DEBUG i=1 st_size=32
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
DEBUG i=2 st_size=0
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
DEBUG i=1 st_size=32
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
DEBUG i=2 st_size=0
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=1 st_size=0
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
DEBUG i=2 st_size=32
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
DEBUG i=1 st_size=32
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=2 st_size=32
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6
[Starter][422287]: contents read from the read end pipe: 10
DEBUG i=0 st_size=0
DEBUG i=0 st_size=32
DEBUG: i=0 shms=4 voidarr=0x7f98e1e54000 my_array3='SHM_lucas'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=1 st_size=0
DEBUG i=1 st_size=32
DEBUG: i=1 shms=5 voidarr=0x7f98e1e53000 my_array3='SHM_hexagonalseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
DEBUG i=2 st_size=0
DEBUG i=2 st_size=32
DEBUG: i=2 shms=6 voidarr=0x7f98e1e52000 my_array3='SHM_harmonicseries'
DEBUG/PROBE: probe=0
[Starter]: 422287 and ]
[Starter][422287] : Created Shared memory "SHM_lucas" with FD: 4
[Starter][422287] : Created Shared memory "SHM_hexagonalseries" with FD: 5
[Starter][422287] : Created Shared memory "SHM_harmonicseries" with FD: 6