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

故事是这样的,有一天客户报了个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.c
weeds@weeds-T68G:~/love/proc$ ./file
35: fd=3
fd -> filename: 3 -> /home/weeds/love/proc/test.txt
38: ret=0
44: fd_A=3
fd -> filename: 3 -> /home/weeds/love/proc/system.txt
47: ret=0
54: ret_A=0
fd -> filename: 3 -> /home/weeds/love/proc/system.txt
62: ret=10
64: ret=0
66: ret=-1
weeds@weeds-T68G:~/love/proc$ cat system.txt
xxxxxweeds@weeds-T68G:~/love/proc$ cat text.txt
weeds@weeds-T68G:~/love/proc$ 

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

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

钱国正

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值