2011-10-06 16 views
2

Valgrind가 내게 다음과 같은 오류 메시지를 표시합니다. -Valgrind - 초기화되지 않은 값과 바이트?

Syscall param write(buf) points to uninitialised byte(s) 

Conditional jump or move depends on uninitialised value(s) 

이 문제를 해결하는 방법을 알 수 없습니다. 모든 오류는 같은 위치에 있습니다. TCP 클라이언트가 클라이언트와 통신 할 수있는 기능이 있습니다. 모든 클라이언트에서 메시지를 수신하면 해당 메시지를 다른 기능으로 전달합니다. 이 함수를 호출하면 모든 오류가 발생합니다. 불행히도 Valgrind는 함수의 행 번호를주지 않습니다. 그냥

by 0x805683F: TcpServer::getSendBack(char*, char) (basic_string.h:2503). 

==8759== 1 errors in context 1 of 5: 
==8759== Syscall param write(buf) points to uninitialised byte(s) 
==8759== at 0x446CFDB: ??? (syscall-template.S:82) 
==8759== by 0x4416B3E: new_do_write (fileops.c:530) 
==8759== by 0x4416E55: [email protected]@GLIBC_2.1 (fileops.c:503) 
==8759== by 0x441793C: [email protected]@GLIBC_2.1 (fileops.c:881) 
==8759== by 0x4416C87: [email protected]@GLIBC_2.1 (fileops.c:1358) 
==8759== by 0x440CA9D: fwrite (iofwrite.c:45) 
==8759== by 0x4300DE5: __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char>  >::xsputn(char const*, int) (in /usr/lib/libstdc++.so.6.0.13) 
==8759== by 0x4303691: std::basic_ostream<char, std::char_traits<char> >&  std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char,  std::char_traits<char> >&, char const*, int) (in /usr/lib/libstdc++.so.6.0.13) 
==8759== by 0x8056825: TcpServer::getSendBack(char*, char) (ostream:510) 
==8759== by 0x805729C: TcpServer::communicate() (tcpserver.cpp:369) 
==8759== by 0x805B7B1: ServerControl::control() (servercontrol.cpp:173) 
==8759== by 0x804FE6E: main (main.cpp:230) 
==8759== Address 0x4028110 is not stack'd, malloc'd or (recently) free'd 
==8759== Uninitialised value was created by a stack allocation 
==8759== at 0x8056FA6: TcpServer::communicate() (tcpserver.cpp:304) 

그리고 다른 오류 -

==8759== 1 errors in context 2 of 5: 
==8759== Conditional jump or move depends on uninitialised value(s) 
==8759== at 0x4416D8C: [email protected]@GLIBC_2.1 (fileops.c:1317) 
==8759== by 0x440CA9D: fwrite (iofwrite.c:45) 
==8759== by 0x4300DE5: __gnu_cxx::stdio_sync_filebuf<char, std::char_traits<char> >::xsputn(char const*, int) (in /usr/lib/libstdc++.so.6.0.13) 
==8759== by 0x4303691: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, int) (in /usr/lib/libstdc++.so.6.0.13) 
==8759== by 0x805683F: TcpServer::getSendBack(char*, char) (basic_string.h:2503) 
==8759== by 0x805729C: TcpServer::communicate() (tcpserver.cpp:369) 
==8759== by 0x805B7B1: ServerControl::control() (servercontrol.cpp:173) 
==8759== by 0x804FE6E: main (main.cpp:230) 
==8759== Uninitialised value was created by a stack allocation 
==8759== at 0x8056FA6: TcpServer::communicate() (tcpserver.cpp:304) 

main 230은 servercontrol과 servercontrol에서 control 함수에 대한 호출 일뿐입니다. 173은 pthread_create 호출입니다.

왜 누군가가 이러한 오류가 발생하는지 파악하는 데 도움을 줄 수 있다면 매우 감사 할 것입니다. 의사 소통 기능은 다음과 같습니다. -

void TcpServer::communicate() { 


fd_set read_flags, write_flags; // the flag sets to be used 
int sel;  // holds return value for select(); 
int numRead = 0; //holds return value for read() 
int numSent = 0; //holds return value for send() 
char in[255]; //in buffer for client 1 
char out[512]; //out buffer 

//clear buffers 
memset(&in, 0, 255); 
memset(&out, 0, 512); 

int nfds = 0; 
for(int i=0;i<count;i++) 
    nfds += clients[i].fd; 

while(!done) { 
    //reset the fd_sets 
    FD_ZERO(&read_flags); 
    FD_ZERO(&write_flags); 
    FD_SET(STDIN_FILENO, &read_flags); 
    FD_SET(STDIN_FILENO, &write_flags); 

    //put fds back in 
    for(int i=0;i<count;i++) { 
     FD_SET(clients[i].fd, &read_flags); 
     FD_SET(clients[i].fd, &write_flags); 
    } //end for 

    //call select 
    sel = select(nfds+1, &read_flags, &write_flags, (fd_set*)0, 0); 

    //if an error with select 
    if(sel < 0) 
     continue; 

    //loop through clients 
    for(int i=0;i<count;i++) { 
     //check if ready for reading 
     if(FD_ISSET(clients[i].fd, &read_flags)) { 

      //clear set 
      FD_CLR(clients[i].fd, &read_flags); 
      //clear in 
      memset(&in, 0, 255); 

      numRead = recv(clients[i].fd, in, 255, 0); 
      if(numRead < 0) { 
       printf("\nError reading from Client 1: %m", errno); 
       clients[i].agent->getRobot()->pauseSensorStream(); 
       done = true; 
      } //end if error 
      //if connection closed, exit 
      else if(numRead == 0) { 
       printf("\nClosing socket"); 
       close(clients[i].fd); 
       done = true; 
       i = count; 
      } //end if connection closed 
      //if message, call getsendback 
      else if(in[0] != '\0') { 
       if(read_mess) 
        std::cout<<"\nMessage successfully received from Client "<<clients[i].id<<": "<<in; 
       getSendBack(in, clients[i].id); 
      } //end if message 
     } //end if 
    } //end for 



    /*CHECK FOR STDIN*/ 

    //if stdin is ready for reading 
    if(FD_ISSET(STDIN_FILENO, &read_flags)) { 
     fgets(out, 512, stdin); 

     //if changing the view 
     if(out[0] == 'v') { 
      std::string temp(out); 
      char w = temp.substr(2, 1)[0]; 
      which_display = w; 
     } //end if changing the view 

     //else check for writing 
     else { 

      for(int i=0;i<count;i++) { 
       //if a socket is reading for writing 
       if(FD_ISSET(clients[i].fd, &write_flags)) { 

        //clear set 
        FD_CLR(clients[i].fd, &write_flags); 

        //if not changing the view and begins with a digit or quitting 
        if(is_id(out[0]) || out[0] == 'q') { 

         //create message to send 
         std::stringstream tosend; 

         //if not the quit command 
         if(out[0] != 'q') { 

          //make a temp of out to substr out the client id 
          std::string temp(out); 
          tosend<<"@ "<<temp.substr(2, temp.length() - 2); 
          //std::cout<<"\ntosend: "<<tosend.str(); 

          //send message to the client 
          numSent = send(get_client_fd(out[0]), tosend.str().c_str(), tosend.str().length(), 0); 

         } //end if not the quit command 

         //if quit command 
         else { 

          tosend<<"@ q"; 
          //std::cout<<"\ntosend: "<<tosend.str(); 

          //send message to quit to all clients 
          for(int i=0;i<count;i++) 
           numSent = send(clients[i].fd, tosend.str().c_str(), tosend.str().length(), 0); 

         } //end quit message 

         //if error, exit 
         if(numSent < 0) { 
          printf("\nError sending to Client %c\nMessage: %s\nError message %m", out[0], out, errno); 
          done = true; 
          i = count; 
         } //end if error 

         //if no error and sent_mess is true, print message 
         else if(numSent > 0 && sent_mess) 
          std::cout<<"\nMessage successfully sent to Client "<<out[0]<<": "<<tosend.str(); 

        } //end if not changing view and begins with a digit or quitting 

        //wait for message to get there, then clear 
        usleep(10000); 
        memset(&out, 0, 512); 
       } //end if 
      } //end for 
     } //end if not changing view 
    } //end if stdin ready for reading 
} //end while 
} //END COMMUNICATE 

그리고 문제는 getSendBack이 처음에있는 것입니다. -

void TcpServer::getSendBack(char* command, char client_id) { 
std::string tempCommand(command); 
//std::cout<<"\ntempCommand: "<<tempCommand; 

//count the number of headers 
int num_headers = 0; 
for(int i=0;i<tempCommand.length() && num_headers < 2;i++) 
    if(tempCommand[i] == '@') 
     num_headers++; 

//if no message stacking 
if(num_headers == 1) { 

    //if packet id 1 (update pos/goal/direction) 
    if(tempCommand[2] == '1') { 

     //get position row 
     int prowend = 4; 
     while(isdigit(tempCommand[prowend])) 
      prowend++; 
     std::string p(tempCommand.substr(4, prowend-3)); 
     int prow = atoi(p.c_str()); 
     //std::cout<<"\nprow: "<<prow; 

     //get position column 
     int pcolend = prowend+1; 
     while(isdigit(tempCommand[pcolend])) 
      pcolend++; 
     std::string c(tempCommand.substr(prowend, pcolend-prowend)); 
     int pcol = atoi(c.c_str()); 
     //std::cout<<"\npcol: "<<pcol; 

     //get goal row 
     int growend = pcolend+1; 
     while(isdigit(tempCommand[growend])) 
      growend++; 
     std::string gr(tempCommand.substr(pcolend, growend-pcolend)); 
     int grow = atoi(gr.c_str()); 
     //std::cout<<"\ngrow: "<<grow; 

     //get goal column 
     int gcolend = growend+1; 
     while(isdigit(tempCommand[gcolend])) 
      gcolend++; 
     std::string gc(tempCommand.substr(growend, gcolend-growend)); 
     int gcol = atoi(gc.c_str()); 
     //std::cout<<"\ngcol: "<<gcol; 

     char direction = tempCommand[tempCommand.length()-1]; 
     //std::cout<<"\ndirection: "<<direction; 


     Position temp_pos(prow, pcol); 
     Position temp_goal(grow, gcol); 

     //lock 
     pthread_mutex_lock(&mutex_agent); 

     //set the new information for the client 
     get_client(client_id).agent->setPosition(temp_pos); 
     get_client(client_id).agent->setGoal(temp_goal); 
     get_client(client_id).agent->setDirection(direction); 

     //unlock 
     pthread_mutex_unlock(&mutex_agent); 
    } //end if new goal 


    //else if packet id 2 (change sensor) 
    else if(tempCommand[2] == '2') { 
     int idend = 4; 
     while(isdigit(tempCommand[idend])) 
      idend++; 
     std::string temp(tempCommand.substr(4, idend-2)); 

     //std::cout<<"\ntemp: "<<temp; 
     int id = atoi(temp.c_str()); 

     //if valid id value, set new current sensor 
     if(id > 6 && id < 43) 
      get_client(client_id).agent->getRobot()->setCurrentSensor(id); 
     else 
      std::cout<<"\n"<<id<<" is Invalid id"; 
    } //end if new sensor 

    //else if 5, quit 
    else if(tempCommand[2] == '5') 
     done = true; 

} //end if 1 header 
//else if stacking 
else 
    std::cout<<"\nSTACKED MESSAGE: "<<tempCommand; 
} //END GETSENDBACK 
+1

'초기화되지 않은 값은 0x8056FA6의 스택 할당에 의해 생성되었습니다 : TcpServer :: communicate() (tcpserver.cpp : 304)'304 행은 무엇입니까? –

+0

... getSendBack의 코드는 무엇입니까? – jpalecek

+0

행 304는 TcpServer :: communicate() {void의 첫 번째 행에 불과합니다. getSendBack 코드로 편집하겠습니다. – Sterling

답변

1

문제가 해결되었습니다. 필자는 런타임 동안 메시지를 보내고받는 파일 설명 자의 배열을 가지고 있습니다. 그러나 나는 각각으로부터 메시지를 받기 위해 같은 버퍼를 사용하고 있었다. 각 파일 설명자에서 메시지를 받기 위해 별도의 버퍼를 사용 했더니 더 이상 Valgrind에서 오류를 가져 오지 않습니다.

1

Whar 있습니다 : "MAIN.CPP : 230", tcpserver.cpp : 304? 문제가있는 것 같습니다.

+0

main230은 servercontrol 함수 중 하나를 호출하는 것일뿐입니다. 나는 그 함수가 단지 pthread를 만들기 때문에 그것을 추가하지 않았다. tcpserver304는 단지 무효입니다. TcpServer :: communicate() {. – Sterling