天天看点

pclose() Segmentation fault

简介

pclose函数使用注意,如果入参为空,则会导致程序段错误。

glibc版本

[[email protected] glibc]$ ldd --version
ldd (GNU libc) 2.28
           

pclose()源码

glibc-2.28.tar.gz

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);
}
           
[[email protected] pclose]$ gcc main.c
[[email protected] pclose]$ ./a.out
Segmentation fault (core dumped)
           

调试

yum debuginfo-install glibc-2.28-101.el8.x86_64

[[email protected] pclose]$ gcc -g main.c
[[email protected] 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");
}
           
[[email protected] pclose]$ gcc main.c
[[email protected] 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");
}
           
[[email protected] pclose]$ gcc main.c
[[email protected] pclose]$ ./a.out
test NULL free
           

继续阅读