Valgrind - uninitialized values and bytes?
Valgrind is giving me errors saying -
Syscall param write(buf) points to uninitialised byte(s)
and
Conditional jump or move depends on uninitialised value(s)
I cannot figure out how to fix this. All of the errors are in the same place. I have a function for a tcp server to communicate with its clients. If it receives a message from any client, it passes that message to another function. All of the errors occur when I call this function. Unfortunately, Valgrind doesn't give me a line number for the function, it just says
by 0x805683F: TcpServer::getSendBack(char*, char) (basic_string.h:2503).
The whole error message for one of them is -
==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: _IO_do_write@@GLIBC_2.1 (fileops.c:503)
==8759== by 0x441793C: _IO_file_overflow@@GLIBC_2.1 (fileops.c:881)
==8759== by 0x4416C87: _IO_file_xsputn@@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: Tc开发者_运维问答pServer::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)
And another error -
==8759== 1 errors in context 2 of 5:
==8759== Conditional jump or move depends on uninitialised value(s)
==8759== at 0x4416D8C: _IO_file_xsputn@@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 is just a call to the control function in servercontrol and servercontrol 173 is just a pthread_create call.
If someone can help me figure out why I'm getting these errors I would be very grateful. The communicate function is -
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
And where I'm thinking the problem is in getSendBack is at the very beginning -
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
Whar are : "main.cpp:230", tcpserver.cpp:304 ? they seem to be the problem
I resolved the issue. I have an array of file descriptors that I am separately sending and receiving messages to/from throughout the run-time. But I was using the same buffer for receiving messages from each one. Once I used a separate buffer for receiving messages from each file descriptor, I no longer get the errors from Valgrind.
精彩评论