Search code examples
clinuxmultithreadingucontext

segmentation fault in setcontext


I'm doing some test on how a scheduler schedules a waiting thread and in the process, I want to not let OS to see a waiting thread, so I kill a thread which is waiting on a lock and start it when the lock is released, I think I should save the context of the thread before exiting and restore it when I create it again. Obviously I'm doing something wrong but I can't figure it out. (I'm very new to the subject.)

this is my code so far, it generates segmentation fault with setcontext.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <ucontext.h>

ucontext_t data;
pthread_t pth;
pthread_mutex_t lock1;

void* wake_up(void* arg) {
    printf("going to wake up a thread\n");
    setcontext(&data);
}
void MUTEX_UNLOCK(pthread_mutex_t* lock) {
    pthread_mutex_unlock(lock);
    pthread_create(&pth, NULL, wake_up, NULL);
}
void MUTEX_LOCK(pthread_mutex_t* lock) {    

    getcontext(&data);

    while(1) {      
        if(pthread_mutex_trylock(lock) == 0) {
            printf("got the lock\n");
            break;
        }
        else {              
            printf("going to exit thread\n");
            pthread_exit(NULL);
        }
    }
}

void* routine1(void* param) {
    MUTEX_LOCK(&lock1);
    printf("enter any character to continue\n");
    getchar();
    MUTEX_UNLOCK(&lock1);
}

int main(int argc, char** argv) {

    pthread_mutex_init(&lock1, 0);

    pthread_t thread1[2];  
    int i; 
    for (i = 0; i < 2; i++)
        pthread_create(&thread1[i], NULL, routine1, NULL);  

    while(1);
}

Solution

  • setcontext is not valid when setting the context of a thread which has exited. (The stack pointer points into a stack which has been freed.) So that's why you're getting a crash.

    More in general, getcontext and setcontext are obsolete and extremely strange functions that should not be used unless you have very specific needs regarding cooperative (non-pthreads) multithreading. While you haven't described what you're trying to do, I'm 99% certain that you don't need setcontext to do it.