淘宝商城(天猫)高级技术专家.3年研发+3年性能测试调优/系统测试+4年团队管理与测试架构、研发系统实践. 新舞台新气象, 深化测试基础架构及研发架构,希望能在某个技术领域成为真正的技术大牛。欢迎荐才http://bbs.51testing.com/viewthread.php?tid=120496&extra=&page=1 .邮件: jianzhao.liangjz@alibaba-inc.com,MSN:liangjianzhao@163.com.微博:http://t.sina.com.cn/1674816524

inet_ntoa(remote_addr.sin_addr) 在64位linux下core dump

上一篇 / 下一篇  2008-04-15 21:31:16 / 个人分类:搜索引擎测试技巧

在编写一个网络应用程序,在32位Linux下已经运行了相当长时间,无core dump,移植到64

我都是单进程执行的。

 

 

Program terminated with signal 11, Segmentation fault.

#0 0x0000003a53c75350 instrlen () from /lib64/libc.so.6

(gdb) bt

#0 0x0000003a53c75350 instrlen () from /lib64/libc.so.6

#1 0x0000003a53c45b88 invfprintf () from /lib64/libc.so.6

#2 0x0000003a53c60e09 invsprintf () from /lib64/libc.so.6

#3 0x0000003a53c4b958 insprintf () from /lib64/libc.so.6

#4 0x000000000040156b in socket_server () at getlinuxstat.c:183

#5 0x0000000000401c90 inmain (argc=1, argv=0x7fff4b872328) at getlinuxstat.c:349

(gdb) f 4

#4 0x000000000040156b in socket_server () at getlinuxstat.c:183

183                                                                                                            sprintf(buf_log,"received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));

 

  咨询开发用线程安全inet_ntop函数,但是这样的话,就会用到两个额外的数组。总要有些牺牲的。
使用inet_ntoa的话,就不能够在同一个函数的几个参数里面出席那两次inet_ntoa,或者是第一个inet_ntoa未使用结束之前,不要使用第二个。

更改实现为:

 if ( NULL== (char*) (inet_ntop(AF_INET,&remote_addr.sin_addr.s_addr,str,31)) )

 

详细的代码如下:

int socket_server()

{

   int sockfd,client_fd; /*sock_fd:监听socketclient_fd:数据传输socket */

   struct sockaddr_in my_addr; /*本机地址信息*/

   struct sockaddr_in remote_addr; /*客户端地址信息*/

   int sin_size;

   char recv_buf[MAX_BUF_SIZE]={0};

   int  recv_size=0;

   char send_buf[MAX_BUF_SIZE]={0};

   int   send_size=0;

   int pid;

   int status;

   struct timeval tv;

   struct in_addr clientaddr ;

   char str[32]={0};

   char buf_log[MAX_BUF_SIZE]={0};

 

   enum stat_action action;

   if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

       sprintf(buf_log,"socke errno=%d,desc=%s\r\n",errno,strerror(errno));

       buf_log[strlen(buf_log)]=0;

       writelog(g_logfile,buf_log);

       return 1;

   }

 

  my_addr.sin_family=AF_INET;

  my_addr.sin_port=htons(SERVPORT);

  my_addr.sin_addr.s_addr = INADDR_ANY;

  bzero(&(my_addr.sin_zero),8);

  if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {

     sprintf(buf_log,"bind errno=%d,desc=%s\r\n",errno,strerror(errno));

     buf_log[strlen(buf_log)]=0;

     writelog(g_logfile,buf_log);

     return 1;

  }

  if (listen(sockfd, BACKLOG) == -1) {

    sprintf(buf_log,"bind errno=%d,desc=%s\r\n",errno,strerror(errno));

       buf_log[strlen(buf_log)]=0;

       writelog(g_logfile,buf_log);

    return 1;

   }

   tv.tv_sec= SOCKET_TIMEOUT_SECOND;

   tv.tv_usec=0;

 

   while(1) {

        memset(&remote_addr, 0, sizeof(struct sockaddr));

       sin_size = sizeof(remote_addr);

       if ((client_fd = accept(sockfd, (struct sockaddr *)(&remote_addr), &sin_size)) == -1) {

          sprintf(buf_log,"accept errno=%d,desc=%s\r\n",errno,strerror(errno));

          buf_log[strlen(buf_log)]=0;

          writelog(g_logfile,buf_log);

          continue;

         }

 

       //sprintf(buf_log,"received a connection from %s\n", inet_ntoa(remote_addr.sin_addr));

 

       if ( NULL== (char*) (inet_ntop(AF_INET,&remote_addr.sin_addr.s_addr,str,31)) )

       {

          printf("inet_ntop error,errno=%d,desc=%s\r\n",errno,strerror(errno) );

       }

       sprintf(buf_log,"received a connection from %s\n", str);

 

       buf_log[strlen(buf_log)]=0;

       writelog(g_logfile,buf_log);

 

      if (setsockopt(client_fd,SOL_SOCKET,SO_RCVTIMEO,&tv,sizeof(tv)) == -1)

      {

         sprintf(buf_log,"warning!setsockopt errno=%d,desc=%s\r\n",errno,strerror(errno));

        buf_log[strlen(buf_log)]=0;

        writelog(g_logfile,buf_log);

      }

 

      if ( (pid=fork()) == 0) { /*子进程代码段*/

          while(1)

          {

            memset(recv_buf,0,MAX_BUF_SIZE);

            recv_size=recv(client_fd,recv_buf,MAX_BUF_SIZE -1 ,0);

            if(recv_size ==-1)

            {

               sprintf(buf_log,"recv errno=%d,desc=%s\r\n",errno,strerror(errno));

                buf_log[strlen(buf_log)]=0;

               writelog(g_logfile,buf_log);

               close(client_fd);

               exit(1);

            }

            else if( 0== recv_size)

           {

              sprintf(buf_log,"connection reset by peer!\r\n");

               buf_log[strlen(buf_log)]=0;

               writelog(g_logfile,buf_log);

              exit(1);

           }

            else    //if (1 == recv_size)

            {

 

              action=atoi(recv_buf);

              sprintf(buf_log,"recv_buf=%s,recv_size=%d,action=%d\r\n",recv_buf,recv_size,action);

              buf_log[strlen(buf_log)]=0;

              writelog(g_logfile,buf_log);

              memset(send_buf,0,MAX_BUF_SIZE);

 

              if (exec_command(2,action,send_buf) ==-1 )

               {

                    continue;

               }

 

              send_buf[ strlen(send_buf)] = 0;

              sprintf(buf_log,"begin send...,send_buf=%s\r\n",send_buf);

              buf_log[strlen(buf_log)]=0;

              writelog(g_logfile,buf_log);

              if (send(client_fd, send_buf,strlen(send_buf), 0) == -1) {

                 sprintf(buf_log,"send errno=%d,desc=%s\r\n",errno,strerror(errno));

                  buf_log[strlen(buf_log)]=0;

                  writelog(g_logfile,buf_log);

                 close(client_fd);

                 exit(1);

              }

 

            }

         }

     }

     else if(pid <0)

     {

       sprintf(buf_log,"socket_server fork errno=%s\n",strerror(errno));

       buf_log[strlen(buf_log)]=0;

       writelog(g_logfile,buf_log);

     }

     else

     {

       //parent;

       close(client_fd);

       waitpid(pid,&status,0);

 

      }

 

  }

 return 0;

}


TAG: inet_ntoa inet_ntop 线程安全 linux 搜索引擎测试技巧

 

评分:0

我来说两句

Open Toolbar