Skip to content
Advertisement

How to fix occasional EINVAL error when calling pthread_create

The Problem

When I create a detached thread using the code below, pthread_create will sometimes return EINVAL. I would like to know why this is happening and what I should do to fix it. When the error occurs, the code below will print the following line:

Error creating thread. errno = 22: Invalid argument

What I’ve Tried

I have only observed this issue when running my code in valgrind. Even then, it only sometimes produces this error. Thus, I am inclined to think timing is a factor. I do not think I have a race condition, as this function does not rely on any shared data. Perhaps I have an issue with how I’m using the stack? I’ve been unsuccessful in discovering any helpful clues from the man pages, except that EINVAL means “Invalid settings in ‘attr’.”

I am running my application on Ubuntu 14.04.

The Code

/**
 * Creates a detached thread to receive data from the socket referred to by
 * sockfd.
 */
void recieve_async(int sockfd) {
    pthread_t receive_thread;
    pthread_attr_t attr;
    int error = pthread_attr_init(&attr);
    if (error != 0) {
        printf("attr_init failed. errno = %d: %sn", error, strerror(error));
    }
    error = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if (error != 0) {
        printf("attr_setdetachstate failed. errno = %d: %sn", error,
               strerror(error));
    }
    error = pthread_create(&receive_thread, &attr, receive, (void *)sockfd);
    if (error != 0) {
        printf("Error creating thread. errno = %d: %sn", error,
               strerror(error));
        exit(1);
    }
    pthread_attr_destroy(&attr);
}

Advertisement

Answer

It turns out this is a bug in Valgrind. The error that should really be reported is EAGAIN.

The function receive_async gets called several times per second. Even though I’m creating detached threads, Valgrind’s virtual environment runs much, much slower than the native environment. So the situation was that I was creating threads faster than Valgrind could destroy them. Valgrind imposes a limit on the number of threads it can work with, and the default limit is 500.

I was able to monitor the number of threads my application was using with the command watch ps -o nlwp <pid>. When running it in Valgrind, the number of threads kept on growing, up to 500. When running outside of Valgrind, this number is much more reasonable (around 4) and does not grow indefinitely.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement