Search code examples
cpthreadsmutexheap-memorymemset

Mutex assertion error with non-zero heap


If I allocate memory, free it and then try to allocate a mutex and lock it, I get the message Assertion 'mutex->__data.__owner == 0'. I am not an expert in concurrency or low-level programming but this seems odd to me.

Code

#include <stdlib.h>
#include <string.h>
#include <pthread.h>

void nonzero_heap(){
    void *ptrs[2];
    ptrs[0] = malloc(16);
    memset(ptrs[0], 0x80, 16);
    ptrs[1] = malloc(32);
    memset(ptrs[1], 0x80, 32);
    free(ptrs[0]);
    free(ptrs[1]);
}

int main(){
    nonzero_heap();
    pthread_mutex_t* mutex = malloc(sizeof(pthread_mutex_t));
    pthread_mutex_lock(mutex);
    return 0;
}

Explanation

I am not really sure what nonzero_heap() does (I copy/pasted it) except from the fact that it fills the heap with some garbage and then frees it. Thus later when I allocate the mutex, it probably get's allocated at the same spot and I get this error.

Is there an explanation for this behaviour? Something I am missing?


Solution

  • OK, the solution is silly. I simply didn't initialize the mutex. The reason I didn't think of this was that the above code worked fine with calloc(). I guess omitting initialization will backfire when you least expect it.

    From manpages:

    The pthread_mutex_init() function shall initialize the mutex referenced by mutex with attributes specified by attr. If attr is NULL, the default mutex attributes are used; the effect shall be the same as passing the address of a default mutex attributes object. Upon successful initialization, the state of the mutex becomes initialized and unlocked.

    So in this case:

    int main(){
        nonzero_heap();
        pthread_mutex_t* mutex = malloc(sizeof(pthread_mutex_t));
        pthread_mutex_init(mutex, NULL); # NEW LINE
        pthread_mutex_lock(mutex);
        return 0;
    }