zoukankan      html  css  js  c++  java
  • 写xhttpd服务器时 遇到segmentation fault

    最近写一个类xhttpd服务器时, 读写文件时,碰到了segmentation fault(core dump)

    原因是自己在判断 FILE *fp 时, 在 if 语句中 使 fp = NULL 正确的语法应该是  if(fp == NULL), “=”  使fp 指向了NULL, 在对fp 进行读写操作时产生了段错误。因为指针指向了非法区域。

    知识补充:

      一般产生 segmentation 的原因主要有

      1,内存访问越界

      a) 由于使用错误的下标,导致数组访问越界。

      b) 搜索字符串时,依靠字符串结束符来判断字符串是否结束,但是字符串没有正常的使用结束符。

      c) 使用strcpy, strcat, sprintf, strcmp,strcasecmp等字符串操作函数,将目标字符串读/写爆。应该使用strncpy, strlcpy, strncat, strlcat, snprintf, strncmp, strncasecmp等函数防止读写越界。

     2,多线程程序使用了线程不安全的函数。

    应该使用下面这些可重入的函数,它们很容易被用错:

    asctime_r(3c) gethostbyname_r(3n) getservbyname_r(3n)ctermid_r(3s) gethostent_r(3n) getservbyport_r(3n) ctime_r(3c) getlogin_r(3c)getservent_r(3n) fgetgrent_r(3c) getnetbyaddr_r(3n) getspent_r(3c)fgetpwent_r(3c) getnetbyname_r(3n) getspnam_r(3c) fgetspent_r(3c)getnetent_r(3n) gmtime_r(3c) gamma_r(3m) getnetgrent_r(3n) lgamma_r(3m) getauclassent_r(3)getprotobyname_r(3n) localtime_r(3c) getauclassnam_r(3) etprotobynumber_r(3n)nis_sperror_r(3n) getauevent_r(3) getprotoent_r(3n) rand_r(3c) getauevnam_r(3)getpwent_r(3c) readdir_r(3c) getauevnum_r(3) getpwnam_r(3c) strtok_r(3c) getgrent_r(3c)getpwuid_r(3c) tmpnam_r(3s) getgrgid_r(3c) getrpcbyname_r(3n) ttyname_r(3c)getgrnam_r(3c) getrpcbynumber_r(3n) gethostbyaddr_r(3n) getrpcent_r(3n)

     3,多线程读写的数据未加锁保护。

    对于会被多个线程同时访问的全局数据,应该注意加锁保护,否则很容易造成coredump

     4,非法指针

      a) 使用空指针

      b) 随意使用指针转换。一个指向一段内存的指针,除非确定这段内存原先就分配为某种结构或类型,或者这种结构或类型的数组,否则不要将它转换为这种结构或类型的指针,而应该将这段内存拷贝到一个这种结构或类型中,再访问这个结构或类型。这是因为如果这段内存的开始地址不是按照这种结构或类型对齐的,那么访问它时就很容易因为bus error而core dump。

     5,堆栈溢出

    不要使用大的局部变量(因为局部变量都分配在栈上),这样容易造成堆栈溢出,破坏系统的栈和堆结构,导致出现莫名其妙的错误。  

    知识补充

      core dump

    1,  产生coredump的条件,首先需要确认当前会话的ulimit –c,若为0,则不会产生对应的coredump,需要进行修改和设置。

    ulimit  -c unlimited  (可以产生coredump且不受大小限制)

    若想甚至对应的字符大小,则可以指定:

    ulimit –c [size]

    但当前设置的ulimit只对当前会话有效,若想系统均有效,则需要进行如下设置:

    Ø  在/etc/profile中加入以下一行,这将允许生成coredump文件

    ulimit-c unlimited

    Ø  在rc.local中加入以下一行,这将使程序崩溃时生成的coredump文件位于/data/coredump/目录下:

    echo /data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern 

    注意rc.local在不同的环境,存储的目录可能不同,susu下可能在/etc/rc.d/rc.local

    这些需要有root权限, 在ubuntu下每次重新打开中断都需要重新输入上面的ulimit命令, 来设置core大小为无限.

    2, 当前用户,即执行对应程序的用户具有对写入core目录的写权限以及有足够的空间。

  • 相关阅读:
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯VIP基础练习 矩形面积交
    Java实现 蓝桥杯VIP 基础练习 完美的代价
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    Java实现 蓝桥杯 蓝桥杯VIP 基础练习 数的读法
    核心思想:想清楚自己创业的目的(如果你没有自信提供一种更好的产品或服务,那就别做了,比如IM 电商 搜索)
    在Linux中如何利用backtrace信息解决问题
  • 原文地址:https://www.cnblogs.com/sanerer/p/9481619.html
Copyright © 2011-2022 走看看