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
本身。
此外,不要使用 fpointer1
和 fpointer2
,只需使用 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;
如您所见,它是一个结构,而不仅仅是一个平面指针。
我正在尝试编写一个简单的程序,使用 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
本身。
此外,不要使用 fpointer1
和 fpointer2
,只需使用 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;
如您所见,它是一个结构,而不仅仅是一个平面指针。