• 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

  • 相关阅读:
    使用twisted.web实现代理服务器
    django signal 浅析
    python 中接口的实现
    浅析django的abstract,proxy, managed
    python-twisted系列(1)
    postgresql 函数demo
    django 1.5+ 权限设计浅析
    django 1.7 新特性 --- data migration
    BZOJ 3670 [Noi2014]动物园 (KMP)
    BZOJ 1029 [JSOI2007]建筑抢修 (贪心 + 优先队列)
  • 原文地址:https://www.cnblogs.com/byfei/p/6389842.html
Copyright © 2020-2023  润新知