1. 程式人生 > >select的fd超過1024將會非常危險------FD_SET導致core dump

select的fd超過1024將會非常危險------FD_SET導致core dump

   關於linux select無須多說, 來看程式碼:

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4. #include<unistd.h>
  5. #include<sys/time.h>
  6. #include<sys/types.h>
  7. int main(int argc, char *argv[])
  8. {
  9. if
    (argc != 2)
  10. {
  11. printf( "para error\n");
  12. return -1;
  13. }
  14. struct
    timeval tv;
    // 超時時間
  15. tv.tv_sec = 10;
  16. tv.tv_usec = 500; // 注意單位是微秒
  17. fd_set rdfds;
  18. FD_ZERO(&rdfds); // 描述集初始化
  19. unsigned int n = atoi(argv[ 1]);
  20. printf( "n is %u\n", n);
  21. for( unsigned int i = 0; i < n; i++)
  22. {
  23. FD_SET(i, &rdfds);
  24. }
  25. printf( "to select\n");
  26. select(n, &rdfds, NULL, NULL, &tv);
  27. return 0;
  28. }
       執行結果:

  1. xxxxxx:~/network&gt; g++ -g server.cpp
  2. server.cpp: 34: 2: warning: no newline at end of file
  3. xxxxxx:~/network&gt; ./a.out 2000
  4. n is 2000
  5. Segmentation fault (core dumped)
  6. xxxxxx:~/network&gt; gdb a.out core
  7. GNU gdb 6.6
  8. Copyright (C) 2006 Free Software Foundation, Inc.
  9. GDB is free software, covered by the GNU General Public License, and you are
  10. welcome to change it and/ or distribute copies of it under certain conditions.
  11. Type "show copying" to see the conditions.
  12. There is absolutely no warranty for GDB. Type "show warranty" for details.
  13. This GDB was configured as "i586-suse-linux"...
  14. Using host libthread_db library "/lib/libthread_db.so.1".
  15. warning: Can 't read pathname for load map: Input/output error.
  16. Reading symbols from / lib/libonion.so...done.
  17. Loaded symbols for / lib/libonion.so
  18. Reading symbols from /usr/ lib/libstdc++.so .6...done.
  19. Loaded symbols for /usr/ lib/libstdc++.so .6
  20. Reading symbols from / lib/libm.so .6...done.
  21. Loaded symbols for / lib/libm.so .6
  22. Reading symbols from / lib/libgcc_s.so .1...done.
  23. Loaded symbols for / lib/libgcc_s.so .1
  24. Reading symbols from / lib/libc.so .6...done.
  25. Loaded symbols for / lib/libc.so .6
  26. Reading symbols from / lib/libdl.so .2...done.
  27. Loaded symbols for / lib/libdl.so .2
  28. Reading symbols from / lib/ld-linux.so .2...done.
  29. Loaded symbols for / lib/ld-linux.so .2
  30. Core was generated by `
  31. Program terminated with signal 11, Segmentation fault.
  32. #0 0x080485af in main (argc=-1, argv=0xffffffff) at server.cpp:27
  33. 27 FD_SET(i, &amp;rdfds);
  34. (gdb)
        可見, 程式core在FD_SET處, 為什麼呢, 看看linux原始碼中關於FD_SET的部分吧:

  1. static __inline__ void __FD_SET( unsigned long fd, __kernel_fd_set *fdsetp)
  2. {
  3. unsigned long _tmp = fd / __NFDBITS;
  4. unsigned long _rem = fd % __NFDBITS;
  5. fdsetp->fds_bits[_tmp] |= ( 1UL<<_rem);
  6. }
  7. #define __NFDBITS (8 * sizeof(unsigned long))
  8. typedef struct {
  9. unsigned long fds_bits [__FDSET_LONGS];
  10. } __kernel_fd_set;
  11. #define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)
  12. #define __FD_SETSIZE 1024

        一幕撩人, 一目瞭然。