2011-10-06 91 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 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行只是void TcpServer :: communicate(){的第一行。我將使用getSendBack的代碼進行編輯。 – Sterling

回答

1

我解決了這個問題。我有一組文件描述符,我在整個運行期間分別發送和接收消息。但我使用相同的緩衝區接收來自每個消息的消息。一旦我使用單獨的緩衝區接收來自每個文件描述符的消息,我就不會再從Valgrind獲取錯誤。

1

Whar是: 「main.cpp中:230」,tcpserver.cpp :304? 他們似乎是問題

+0

main230只是調用servercontrol的一個函數。我沒有添加它,因爲該函數只是pthreads。 tcpserver304只是無效TcpServer ::通信(){。 – Sterling