Valgrind - 未初始化的值和字节?

发布于 2024-12-08 08:36:54 字数 11415 浏览 0 评论 0原文

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: _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: 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: _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 只是对 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

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: 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)

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我不是你的备胎 2024-12-15 08:36:54

什么是:“main.cpp:230”,tcpserver.cpp:304?
他们似乎是问题所在

Whar are : "main.cpp:230", tcpserver.cpp:304 ?
they seem to be the problem

青萝楚歌 2024-12-15 08:36:54

我解决了这个问题。我有一个文件描述符数组,在整个运行时中我分别向它们发送和接收消息。但我使用相同的缓冲区来接收来自每个缓冲区的消息。一旦我使用单独的缓冲区从每个文件描述符接收消息,我就不再从 Valgrind 收到错误。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文