Привет.

Столкнулся со странным поведенем программы, запускаемой из отладчика (под gdb). Начал выяснять. Обнаружилось, что если в программе есть несколько нитей, то при "хождении по шагам" нити могут просыпаться, хотя они сидят на вызове sem_wait(&sema), а сам "sema" - ещё имеет нулевой счетчик.

Удивился. Погуглил. Оказывается, с этой проблемой сталкиваются многие, и происходить это может не только под отладчиком (например, запускаем программу, Ctrl-Z, затем fg. Всё, если были нити, которые сидят на семафорах, то они начтут выполняться).

Обход это проблемы тоже был более-менее одинаков - вместо sema_wait() делаем что-то типа "while(sema_wait()==-1);". Документация, оказывается, не соответствует действительности.

Сделал. Проблема ушла. Частично. Теперь уход в background/вывод в foreground происходит корректно. Но. Под отладчиком теперь получаем такое:
Program received signal SIGSEGV, Segmentation fault.

Напоследок проверил отладку под insight - версия в sarge просто отказалась отлаживать эту программу.

Всё. Приплыли. Как вообще можно отлаживать программы - непонятно.

Компилируем так "gcc -o test_thread test_thread.c -g -lpthread "
Вот сам код (test_thread.c), ничего лишнего, примитивней некуда:
#include <unistd.h>
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>

sem_t global_S;

void* test_thread(void* ptr)
{
        int ret=0;
        
        sleep(1);
        printf("1\n");
        sleep(1);
        printf("2\n");
        sleep(1);
        printf("3\n");

        
        ret=sem_post(&global_S);
        if (ret)
                printf("FAIL in thread: 0x%08X\n", ret);

        return 0;
}

int main()
{
        int ret=0;
        pthread_t thread_id;
        
        /* создаём семафор */
        ret=sem_init (&global_S, 0, 0);
        if (ret) goto fail;

        /* создаём и запускаем нить */
        if (pthread_create(&thread_id, NULL,
                test_thread, NULL)!=0)
        {
                ret=-2;
                goto fail;
        }


        /* ждём семафора */
        {
                int rc=0;
                {
                        rc=sem_wait(&global_S);
                } while(rc==-1);
        }

        /* освобождаем выделенные ресурсы */
        ret=sem_destroy(&global_S);
        if (ret) goto fail;

        printf("all ok\n");
        return 0;

fail:
        printf("FAIL: ret=0x%08X\n", ret);
        return 1;
}



Версии программ (gcc, gdb, insight)- из Sarge. Ядро 2.6.15 из backports

--
  С уважением, Василий.


--
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Ответить