How to detect which piece of my code is generating "Fatal error: glibc detected an invalid stdio handle" error?

How to detect which piece of my code is generating "Fatal error: glibc detected an invalid stdio handle" error?

我正在尝试编写一个简单的程序,使用 2 个进程将文件复制到另一个文件。 我想用共享内存打开这两个文件,以互斥的方式得到一块1Byte的共享内存作为交换内存。

所以主进程应该打开这两个文件并将它们放在共享内存中; fork 两次,我得到 2 个进程 A 和 B。 进程 A 应该读取第一个文件的 1 个字节,将其放入共享交换内存并为进程 B 解锁互斥量。 进程 B 应该从共享交换内存中复制文件并将其放入其文件中,并为进程 A 解锁互斥量。 等等。

#define SIZE 4096

void reader_process(FILE* fptr,char*exch, sem_t*mut){
    while(1){
        sem_wait(mut);
        *exch = (char) getc(fptr);
        sem_post(mut+1);
    }
}

void writer_process(FILE* fptr,char*exch, sem_t*mut){
    if(*exch == EOF){
        printf("done\n");
        exit(0);
    }

    while(1){
        sem_wait(mut);
        putc((int)*exch,fptr);
        sem_post(mut-1);
    }
}

int main(int argc, char *argv[]){
    FILE* shared_f_ptr[2];
    pid_t pid;
    //2 files name.
    char *files[2];
    int fd[2];

    //open files.
    files[0] = argv[1];
    printf("%s\n",files[0]);
    FILE* fpointer1 = fopen(files[0],"r+");
    if (fpointer1 == NULL){
        perror("fopen\n");
        exit(-1);
    }
    fd[0] = fileno(fpointer1);

    files[1] = argv[2];
    printf("%s\n",files[1]);
    FILE* fpointer2 = fopen(files[1],"r+");
    if (fpointer2 == NULL){
        perror("fopen\n");
        exit(-1);
    }
    fd[1] = fileno(fpointer2);

    //shared File pointers.
    shared_f_ptr[0] = (FILE*)mmap(NULL, SIZE*sizeof(char),
       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
       fd[0], 0);
    if (shared_f_ptr[0] == MAP_FAILED){
        perror("mmap\n");
        exit(-1);
    }

    shared_f_ptr[1] = (FILE*)mmap(NULL, SIZE*sizeof(char),
       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
       fd[1], 0); 
    if (shared_f_ptr[1] == MAP_FAILED){
        perror("mmap\n");
        exit(-1);
    }
    //shared mem for 1B exchange.
    char *shared_exchange = (char*)mmap(NULL, sizeof(char),
    PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS,
     -1, 0);
    if (shared_exchange == MAP_FAILED){
        perror("mmap\n");
        exit(-1);
    }

    //mutex.
    sem_t *mut = (sem_t*)mmap(NULL, 2*sizeof(sem_t),
        PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS,
        -1, 0);
    sem_init(&mut[0],1,0);
    sem_init(&mut[1],1,0);



    //fork.

    pid = fork();
    if (pid == 0) {
        reader_process(shared_f_ptr[0],
        shared_exchange, &mut[0]);
    }
    if (pid == -1){
        perror("fork\n");
        exit(-1);
    }

    else pid = fork();

    if (pid == 0) writer_process(shared_f_ptr[1],
        shared_exchange, &mut[1]);

    if (pid == -1){
        perror("fork\n");
        exit(-1);
    }

    else{
        sem_post(&mut[0]);
    }
}

我没想到我会收到错误 Fatal error: glibc detected an invalid stdio handle 但我真的不知道如何找到导致问题的原因。

不要这样做:

//shared File pointers.
shared_f_ptr[0] = (FILE*)mmap(NULL, SIZE*sizeof(char),
   PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
   fd[0], 0);
if (shared_f_ptr[0] == MAP_FAILED){
    perror("mmap\n");
    exit(-1);
}

shared_f_ptr[1] = (FILE*)mmap(NULL, SIZE*sizeof(char),
   PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
   fd[1], 0); 
if (shared_f_ptr[1] == MAP_FAILED){
    perror("mmap\n");
    exit(-1);
}

改用这个:

shared_f_ptr[0] = fpointer1;
shared_f_ptr[1] = fpointer2;

不要使用每个 FILE 下的文件描述符。相反,只需使用 FILE 本身。

此外,不要使用 fpointer1fpointer2,只需使用 shared_f_ptr[0]shared_f_ptr[1]

这是 FILE 结构的可能定义:

typedef struct _IO_FILE
{
    int __fd;
    int __flags;
    int __unget;
    char *__buffer;
    struct {
        size_t __orig;
        size_t __size;
        size_t __written;
    } __bufsiz;
    fpos_t __fpos;
} FILE;

如您所见,它是一个结构,而不仅仅是一个平面指针。