Valgrind不使用select

时间:2015-09-15 15:16:41

标签: c linux multithreading select valgrind

我遇到了valgrind和select的问题。当我在终端中运行我的应用程序或当我使用gdb运行我的应用程序时,我没有错误。一切都运行良好,如预期的那样。

当我使用valgrind运行我的应用程序时,我收到以下错误:

valgrind --tool=memcheck --leak-check=full ./myservice
==3403== Thread 12:
==3403== Syscall param select(readfds) points to uninitialised byte(s)
==3403==    at 0x41C3E31: ??? (syscall-template.S:81)
==3403==    by 0x805531B: myThread (myservice.c:2062)
==3403==    by 0x40CAF6F: start_thread (pthread_create.c:312)
==3403==    by 0x41CBBED: clone (clone.S:129)
==3403==  Address 0xf5c9f38 is on thread 12's stack
==3403==

我的应用程序本身将打印出以下错误:

Sep 15, 2015 | 10:30:32 | select: Bad file descriptor

我对valgrind很新,所以我不了解valgrind正在做什么来打破选择。相关代码粘贴在下面。

Global Pipe

int pipefd[2];

中断处理程序

void intHandler(int sig) {
    keepRunning = false;
    write(pipefd[1], "terminate", sizeof("terminate"));
}

主要

int main(int   argc, char *argv[]){
    int i = 0;
    ...
    signal(SIGINT, intHandler);
    pipe(pipefd);
    ...
    pthread_t myThreadHandle[10];
    for (i = 0; i < 10; i++) {
        pthread_create(&myThreadHandle[i], NULL, myThread, NULL);
    }
    ...
}

我的主题

void *myThread(void *ptr) {
    struct timeval tv;
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    ...
    int socketfd = 555; //edit: forgot to include socketfd code, this is the error
    ...
    fd_set readfs;
    FD_ZERO(&readfs);
    FD_SET(pipefd[0], &readfs);
    if(select(socketfd+1, &readfs, NULL, NULL, &tv) < 0){ //ln 2062
        snprintf(logMessage, sizeof(logMessage),"select: %s", strerror(errno));
        writeLog(logMessage);
    }
    ...
}

基本上我想优雅地终止我的应用程序。我在main中初始化管道,并使用管道来监视select语句。如果不写入管道,选择将处于空闲状态直到超时。我使用信号处理程序写入管道,因此我的select语句将知道管道已写入并停止等待。

我是如何为多个线程使用一个管道的问题?根据我的理解,select实际上并没有触及数据,只看到它在那里。因此每个线程应该看到管道上的数据,修改自己的fd_set并在超时之前退出select(这与我在gdb中看到的一致)。

修复(编辑) - 使用错误的nfds值进行选择,使用readfs中的pipefd进行更正。

    if(select(pipefd[0]+1, &readfs, NULL, NULL, &tv) < 0){ //ln 2062

0 个答案:

没有答案