• bug注意事项


    二个64位的数据,相减后如果为64位的负数,用int强转以后,结果是为正数。


    char *buffer = calloc(sz*2+1, sizeof(char));
    先分配一块内存,长度是要 dump 的数据长度两倍加一。然后循环
    sprintf(buffer+i*2, "%02x", data[i]);
    这就是我们看了几次没留意的 bug 所在:data 是 const char 类型,有符号的。当 data[i] 是一个负数时, %02x 不一定只输出  3 个字节(别忘记字符串结尾的 )。buffer 这块内存就被写越界了。

    一起 select 引起的崩溃

    rabbitmq-c 为了控制 connect 的超时时间,使用了非阻塞 connect ,然后使用 select 判断 fd 是否可写来判定连接是否建立。 select 调用未考虑 sockfd 大于 FD_SETSIZE 。linux 的 select 手册中有这样一行注释:
    Anfd_set is a fixed size buffer. Executing FD_CLR() or FD_SET() with a value of fd that is negative or is equal to or larger than FD_SETSIZE will result in undefined behavior. Moreover, POSIX requires fd to be a valid file descriptor.
    这是一个很容易被程序员忽视的坑。FD_SET 其实是一个位数组,linux 默认是 1024 bit 。而 FD_SET 只是简单的把 fd 当作一个序号按位向位数组写数据。select 应该也是如此。所以当 fd 大于 1024 时,就会写越界。正确的方法是当需要 select 的 fd 大于等于 1024 时,最好在堆上分配 FD_SET ,分配空间应至少保证 fd/8 + 1 以上;或者用 poll / WSAPoll 更好。
    一般的程序不会有这个问题是因为通常一个进程需要的文件 fd 不会超过 1024 。而我们的系统管理了大量的外部连接,超过 1024 轻而易举。之前,机房间的网络正常,只在程序启动时创建连接一次连接。这时尚无外部连接,这个连接的 fd 一定是小于 1024 的,而之后也不会发生重连。
    http://blog.codingnow.com/2014/02/select_bug.html#more

  • 相关阅读:
    易用网页下载器V0.1
    重复造轮之权限管理系统
    网页格式化排版代码,专用信息采集后的内容整理
    随机点名软件
    PHP导入Excel表格,读取Excel的内容到数组。
    汉字的书写效果的实现
    php的一个断点续传下载实现
    sentry的安装和使用以及各种问题处理
    CentOS下安装Redis及Redis的PHP扩展
    用ASP.NET_Regsql.exe创建Session数据库
  • 原文地址:https://www.cnblogs.com/byfei/p/14104442.html
Copyright © 2020-2023  润新知