尝试从管道访问 void * 中的数据后收到总线错误

Receiving Bus Error after trying to access data in void * from pipe

我目前正在编写一个程序,根据输入文件中的数字计算卢卡斯级数、六角级数和谐波级数。我正在使用管道和共享内存段在程序之间共享值。

我从创建管道开始

int p[2];
if (pipe(p) < 0)
    fprintf(stderr, "Problem opening pipe!\n");

然后我运行一个子进程将输入文件的内容读取到我的管道中,其中argv[1]是输入文件的名称(后面使用了maxPrime但这里没有)

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);
}

最后,这是我在尝试访问名为 voidarr 的空指针数组时遇到总线错误的地方。程序的这一部分是我分叉子进程以获取它们各自系列中数字的总和并将它们打印到标准输出的地方。

shms是文件描述符的int数组,voidarr是指向共享内存的void *数组,pidArray是存放每个子进程的进程ID

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]);
    }
}

这就是我的输出结果

[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)

此外,我不知道是否需要回答这个问题,但这是我的 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;
}

您的问题是,在执行 shm_open 之后,对 return 值执行 fstat 显示 st_size 值为 0!

最初,来自 shm_open 的描述符大小为零。必须明确地给它一个大小。请注意,仅将 32 指定为 mmap 的长度 而不是 会导致文件扩展。

这必须用 ftruncate 完成。

shm_open调用后,您需要做的是:

ftruncate(shms[i],32);

这是针对您的 github 存储库的补丁。即使没有它,它也会显示所需的更改:

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]);

修改后的程序输出如下:

./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