Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi thread issue in 'leak_enabled_check'. #27

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

scaro-axway
Copy link

Hi,

After using the library intensively on a program, I noted some weird unexpected traces in the log file:

# switch enabled.
# switch enabled.
# switch enabled.

Investigating what could cause it, it turned out there is threading issue in function 'leak_enabled_check': when accessed concurrently, the method sets temporarily the static variable 'leak_enabled' to false, which affects the other threads running.

Here is a test code I used to reproduce the issue (with variable LEAK_PID_CHECK=1):

#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>
#include <ctype.h>


static volatile int stop = 0;
static unsigned long long malloc_count = 0;
static unsigned long long free_count = 0;

static void *local_malloc(size_t len)
{
    __sync_fetch_and_add(&malloc_count, 1);
    return malloc(len);
}

static void local_free(void *addr)
{
    __sync_fetch_and_add(&free_count, 1);
    free(addr);
}

static void allocate_rand() {
    size_t alloc_count = 100; // + rand()%1000;
    void **data = calloc(alloc_count, sizeof(void *));

    for (size_t cpt = 0; cpt < alloc_count; cpt++) {
        size_t alloc_size = 1 + rand()%10000; // 10 Ko max
        data[cpt] = local_malloc(alloc_size);
        if (data[cpt] == 0) {
            printf("ERROR: allocation of %lu failed\n", alloc_size);
            break;
        }
    }
    for (size_t cpt = 0; cpt < alloc_count; cpt++) {
        if (data[cpt] == 0)
            break;
        local_free(data[cpt]);
    }
    free(data);
}

static void *thread_alloc_run(void *arg) {
    while (! stop) {
        allocate_rand();
    }
    pthread_exit(EXIT_SUCCESS);
}

static void *thread_timer_run(void *arg) {
    unsigned int delay = *(unsigned int *)arg;
    printf("Waiting %u\n", delay);
    sleep(delay);
    printf("Timeout reached.\n");
    pthread_exit(EXIT_SUCCESS);
}

int main(int argc, char const *argv[])
{
    size_t threads_count = 100;

    if (argc > 1) {
        if (isdigit(argv[1][0]))
            threads_count = atoi(argv[1]);
    }

    unsigned int delay_s = 20;
    pthread_t threads[threads_count];
    pthread_t thread_timer;

    printf("Starting threads %lu\n", threads_count);
    for (size_t i = 0; i < threads_count; i++) {
        pthread_create(&threads[i], NULL, thread_alloc_run, NULL);
    }
    printf("Starting timer \n");
    pthread_create(&thread_timer, NULL, thread_timer_run, &delay_s);
    pthread_join(thread_timer, NULL);
    printf("Stopping threads ...\n");
    stop = 1;
    for (size_t i = 0; i < threads_count; i++) {
        pthread_join(threads[i], NULL);
    }
    printf("Calls to malloc: %llu\n", malloc_count);
    printf("Calls to free: %llu\n", free_count);

    return 0;
}

No issue when code is run on a single thread, while some "may-leak" are randomly reported when using more threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant