libunwind-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Libunwind-devel] A test cast for unwind the stack contains __lll_unlock


From: Chenggang
Subject: [Libunwind-devel] A test cast for unwind the stack contains __lll_unlock_wake
Date: Fri, 19 Dec 2014 17:06:21 +0800 (CST)

Hi:
     Some days ago, I report a error while walk through __lll_unlock_wake(). This is a function of ntpl of glibc (libpthread).
     The version of libunwind I used is upstream. The top commit is : c90a2e02b3c1b03362a549a05261a4d0513d6026

    I write a simple test program to verify the effective of unwind __lll_unlock_wake(). I got the result:
=========The right >
/lib64/libpthread-2.5.so: 0x319720d6d5         ## __lll_unlock_wake
/lib64/libpthread-2.5.so: 0x319720a157         ## _L_unlock_766
/lib64/libpthread-2.5.so: 0x319720a0be         ## pthread_mutex_unlock
/bianque/benchmark/lock/mutex: 0x400ae7   ## counter_func_1
/bianque/benchmark/lock/mutex: 0x400b4b   ## counter_func_2
/bianque/benchmark/lock/mutex: 0x400b6b   ## counter_func_3
/bianque/benchmark/lock/mutex: 0x400b8b   ## counter_thread
/lib64/libpthread-2.5.so: 0x319720677d         ## start_thread
/lib64/libc-2.5.so: 0x3196ad49ad                   ## __clone

=========The wrong >
/lib64/libpthread-2.5.so: 0x319720d6d5         ## __lll_unlock_wake
/bianque/benchmark/lock/mutex: 0x400b4b   ## counter_func_2
/bianque/benchmark/lock/mutex: 0x400b6b   ## counter_func_3
/bianque/benchmark/lock/mutex: 0x400b8b   ## counter_thread
/lib64/libpthread-2.5.so: 0x319720677d         ## start_thread
/lib64/libc-2.5.so: 0x3196ad49ad                   ## __clone

The wrong result skip 3 frames (_L_unlock_766, pthread_mutex_unlock, counter_func_1). 
I suspect that the value of the CFA is miscalculated while through  __lll_unlock_wake. 
In the other complex example, we cannot get any frame above __lll_unlock_wake.

The test program I used:
-------------------------------------------
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

#define SPIN 10000000  

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
long counter;
time_t end_time;

void* counter_func_1(void* arg)
{
    int status;
    int spin;

    while(1) {
        status = pthread_mutex_lock(&mutex);
        if(status != 0)
            fprintf(stderr, "Lock mutex\n");

        for(spin = 0; spin < SPIN; spin++)
            counter++;

        status = pthread_mutex_unlock(&mutex);
        if(status != 0)
            fprintf(stderr, "Unlock mutex\n");
    }

    printf("Coutner is %#lx\n", counter);

    return NULL;
}

void* counter_func_2(void* arg)
{
    counter_func_1(NULL);

    return NULL;
}

void* counter_func_3(void* arg)
{
    counter_func_2(NULL);

    return NULL;
}

void* counter_thread(void* arg)
{
    counter_func_3(NULL);

    return NULL;
}


void* monitor_thread(void* arg)
{
    int status;
    int misses = 0;

    while(time(NULL) < end_time)
    {
        status = pthread_mutex_trylock(&mutex);
        if(status != EBUSY)
        {
            if(status != 0)
                fprintf(stderr, "Trylock mutex");

            printf("Counter is %ld/n", counter/SPIN);
            status = pthread_mutex_unlock(&mutex);
            if(status != 0)
                fprintf(stderr, "Unlock mutex");
        }else
            misses++;
    }
    printf("Monitro thread missed update %d times./n", misses);
    return NULL;
}

#define THREAD_ARRAY_NUM 200
int main()
{
    int status;
    pthread_t pid_counter;
    pthread_t pid_monitor;
    pthread_t pid_array[THREAD_ARRAY_NUM];

    end_time = time(NULL) + 600000000;

    status = pthread_create(&pid_counter, NULL, counter_thread, NULL);
    if(status != 0)
        fprintf(stderr, "fail to create thread counter");

    status = pthread_create(&pid_monitor, NULL, monitor_thread, NULL);
    if(status != 0)
        fprintf(stderr, "fail to create monitor thread");

    for (int i = 0; i < THREAD_ARRAY_NUM; i++) {
        status = pthread_create(&pid_array[i], NULL, counter_thread, NULL);
        if (status != 0)
            fprintf(stderr, "fail to create array thread: %d\n", i);
    }

    status = pthread_join(pid_counter, NULL);
    if(status != 0)
        fprintf(stderr, "fail to join counter thread");

    status = pthread_join(pid_monitor, NULL);
    if(status != 0)
        fprintf(stderr, "fail to join monitor thread");

    for (int i = 0; i < THREAD_ARRAY_NUM; i++) {
        pthread_join(pid_array[i], NULL);
    }

    return 0;
}

Compiler command is :
g++ -O3 -fno-inline -o mutex mutex.cc -lpthread

Regards
Chenggang



reply via email to

[Prev in Thread] Current Thread [Next in Thread]