交换上下文后的分段错误

时间:2015-01-18 22:39:04

标签: c segmentation-fault

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

输出: 在上下文init之前 在上下文交换之前 信息 消息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);
}

1 个答案:

答案 0 :(得分:0)

原因是您在两种情况下同时重复使用堆栈;也就是说,虽然两种情境都是有效的。 makecontext用一些东西初始化堆栈(不确定究竟是什么,但可能是一个链接回前一个上下文的返回地址),因此一个破坏了另一个。

在第一个上下文运行后,将调用简单地移动到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);
}