交换上下文后出现分段错误

Segmentation fault after swap context

为什么在执行以下代码时会出现段错误?我注意到如果我声明第二个堆栈( char s2[10000]; 和 init_context2(&unew2, s2, 10000);)一切正常。但是我不明白为什么需要两个堆栈。是否可以只用一个,如果可以怎么用?

输出: 在上下文初始化之前 上下文交换之前 信息 留言2 分段错误

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>    
ucontext_t uold, unew, unew2;
char s1[10000];

static void message()
{
    puts("Message");
}

static void message2()
{
    puts("Message2");
}

void init_context(ucontext_t * uc, void* stack, size_t stack_size)
{
    //puts("Inside init context");
    getcontext(uc);
    uc->uc_link = &uold;
    uc->uc_stack.ss_sp = stack;
    uc->uc_stack.ss_size = stack_size;
    uc->uc_stack.ss_flags = 0;
    makecontext(uc, message, 0);
}

void init_context2(ucontext_t * uc, void* stack, size_t stack_size)
{
    //puts("Inside init context 2");
    getcontext(uc);
    uc->uc_link = &uold;
    uc->uc_stack.ss_sp = stack;
    uc->uc_stack.ss_size = stack_size;
    uc->uc_stack.ss_flags = 0;
    makecontext(uc, message2, 0);
}

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

    int i;
    for(i=0; i<10; i++)
    {
        puts("before context init");
        init_context(&unew, s1, 10000);
    init_context2(&unew2, s1, 10000);
    puts("before context swap");
    swapcontext(&uold, &unew);
    swapcontext(&uold, &unew2);
    }

    return (EXIT_SUCCESS);
}

原因是您在两个上下文中同时重用堆栈;也就是说,虽然两个上下文都有效。 makecontext 用某些东西初始化堆栈(不确定到底是什么,但可能是链接回先前上下文的 return 地址),因此一个会破坏另一个。

只需将对 init_context2() 的调用移动到第一个上下文 运行 之后即可使程序运行:

for(i=0; i<10; i++)
{
    puts("before context init");
    init_context(&unew, s1, 10000);
    puts("before context swap");
    swapcontext(&uold, &unew);
    init_context2(&unew2, s1, 10000);
    swapcontext(&uold, &unew2);
}