添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

误将fclose写成pclose引发的惨案

fopen/fclose配对大家都是知道的,popen/pclose可能比较少用。同事写代码时,误写成fopen/pclose,然后在安卓6.0上文件句柄泄露了,然后各种神奇的崩溃。

同时,我很奇怪的发现,我自己的手机一点问题没有,这不科学。那我们就用安卓源码来说话吧。

Android 6.0

int
191  pclose(FILE *iop)
192  {
193  	struct pid *cur, *last;
194  	int pstat;
195  	pid_t pid;
197  	_DIAGASSERT(iop != NULL);
199  	rwlock_wrlock(&pidlist_lock);
201  	/* Find the appropriate file pointer. */
202  	for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
203  		if (cur->fp == iop)
204  			break;
205  	if (cur == NULL) {
206  		(void)rwlock_unlock(&pidlist_lock);
207  		return (-1);
208  	}
210  	(void)fclose(iop);
212  	/* Remove the entry from the linked list. */
213  	if (last == NULL)
214  		pidlist = cur->next;
215  	else
216  		last->next = cur->next;
218  	(void)rwlock_unlock(&pidlist_lock);
220  	do {
221  		pid = waitpid(cur->pid, &pstat, 0);
222  	} while (pid == -1 && errno == EINTR);
224  	free(cur);
226  	return (pid == -1 ? -1 : pstat);
227  }

这段代码来自bionic的upstream-netbsd,可见如果在pidlist里找不到的话,就直接返回了,如果找得到就调用fclose+waitpid。

Android master

446  int fclose(FILE* fp) {
447    CHECK_FP(fp);
448    return __FILE_close(fp);
449  }