多写一个close()惹下的祸(PS:犯错的不是我,我只是个解bug的)

来源:互联网 发布:java json tobean 编辑:程序博客网 时间:2024/04/29 19:47

故事是这样的,有一天客户报了个bug,说我们camera的configuration file坏啦,我们也不知道问题怎么样,只是知道客户那里存在这种问题,怎么办呢,在写configuration file的时候加锁,让它只能一个写,这样我们自以为解了,其实是没找到重现都办法,没法解啊,只能内部加强。

问题重现:

 

#include <stdio.h>#include <unistd.h>#include <stdlib.h>void get_filename_by_fd(int fd){int MAXSIZE = 0xFFF;    char proclnk[0xFFF];    char filename[0xFFF];    ssize_t r;        sprintf(proclnk, "/proc/self/fd/%d", fd);r = readlink(proclnk, filename, MAXSIZE);if (r < 0){printf("failed to readlink\n");return;}filename[r] = '\0';printf("fd -> filename: %d -> %s\n", fd, filename);}int main(){        FILE *fp, *fp_A;    int fno, fno_A;    int ret, ret_A;        // test.txt created earlier    fp = fopen("test.txt", "w+");    if (fp != NULL)    {        fno = fileno(fp);    }    printf("%d: fd=%d\n", __LINE__, fno);    get_filename_by_fd(fno);    ret = close(fno);// extra close    printf("%d: ret=%d\n", __LINE__, ret);    fp_A = fopen("system.txt", "w+");    if (fp_A != NULL)    {        fno_A = fileno(fp_A);    }    printf("%d: fd_A=%d\n", __LINE__, fno_A);    get_filename_by_fd(fno);    ret = fclose(fp); // close the fp    printf("%d: ret=%d\n", __LINE__, ret);    fp = fopen("text.txt", "w+");    if (fp != NULL)    {        fno = fileno(fp);    }    ret_A = fclose(fp_A); // close the fp_A    printf("%d: ret_A=%d\n", __LINE__, ret_A);    fp_A = fopen("system.txt", "w+");    if (fp_A != NULL)    {        fno_A = fileno(fp_A);    }    get_filename_by_fd(fno);    ret= write(fno, "xxxxx", 10);    printf("%d: ret=%d\n", __LINE__, ret);    ret = close(fno); // extra fp    printf("%d: ret=%d\n", __LINE__, ret);    ret = fclose(fp); // cloase the fp    printf("%d: ret=%d\n", __LINE__, ret);    return 0;}

程序都结果肯定出乎你都意料之外。

weeds@weeds-T68G:~/love/proc$ gcc -o file file.cweeds@weeds-T68G:~/love/proc$ ./file35: fd=3fd -> filename: 3 -> /home/weeds/love/proc/test.txt38: ret=044: fd_A=3fd -> filename: 3 -> /home/weeds/love/proc/system.txt47: ret=054: ret_A=0fd -> filename: 3 -> /home/weeds/love/proc/system.txt62: ret=1064: ret=066: ret=-1weeds@weeds-T68G:~/love/proc$ cat system.txtxxxxxweeds@weeds-T68G:~/love/proc$ cat text.txtweeds@weeds-T68G:~/love/proc$ 

其实吧,这个很简单,是系统VFS给你申请的文件描述符基本递增的,而当你多写了个close,而恰巧在第二个fclose之前打开啦另外一个文件,那么就会导致你的程序紊乱啦,这种问题异常都难于解决,建议写程序都时候多用心。

 


0 0