天天看點

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
           

繼續閱讀