如何检测我的代码的哪一部分正在生成“致命错误:glibc检测到无效的stdio句柄”错误?

时间:2019-07-18 15:31:41

标签: c operating-system glibc stdio

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

因此,主进程应打开两个文件并将它们放入共享内存中; 分叉两次,获得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的错误,但我真的不知道如何找到导致问题的原因。

1 个答案:

答案 0 :(得分:0)

不要这样做:

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

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