简介
pclose函数使用注意,如果入参为空,则会导致程序段错误。
glibc版本
[xiaofeng@localhost glibc]$ ldd --version
ldd (GNU libc) 2.28
pclose()源码
pclose.c
/* POSIX does not require us to check that a stream passed to pclose()
was created by popen(). Instead we rely on _IO_SYSCLOSE to call
_proc_close when appropriate. */
int
__new_pclose (FILE *fp)
{
return _IO_new_fclose (fp);
}
验证
main.c
#include <stdio.h>
int main()
{
FILE *p =NULL;
pclose(p);
}
[xiaofeng@localhost pclose]$ gcc main.c
[xiaofeng@localhost pclose]$ ./a.out
Segmentation fault (core dumped)
调试
yum debuginfo-install glibc-2.28-101.el8.x86_64
[xiaofeng@localhost pclose]$ gcc -g main.c
[xiaofeng@localhost pclose]$ gdb ./a.out
(gdb) r
Starting program: /home/xiaofeng/workspace/tmp/pclose/a.out
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a82a98 in _IO_new_fclose (fp=0x0) at iofclose.c:48
48 if (fp->_flags & _IO_IS_FILEBUF)
fp->_flags 由于fp为NULL,所以此处会段错误
拓展
free()函数
- double free
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p1 = malloc(1);
free(p1);
free(p1);
printf("test double free\n");
}
[xiaofeng@localhost pclose]$ gcc main.c
[xiaofeng@localhost pclose]$ ./a.out
free(): double free detected in tcache 2
Aborted (core dumped)
- NULL free
man 3 free
If ptr is NULL, no operation is performed.
如果ptr是NULL,则没有什么操作被执行。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p1 = malloc(1);
free(p1);
free(p1);
printf("test double free\n");
}
[xiaofeng@localhost pclose]$ gcc main.c
[xiaofeng@localhost pclose]$ ./a.out
test NULL free