1

我写了一个简单的程序,使用ucontext库。但是,发生了信号 SIGSEGV(地址边界错误)。运行环境是 MacOS。我不知道我做错了什么?

此处更新:版本 2

正如@Jeremy 建议的那样,我们可以在and上使用static。但是,如果我们换成数组,还是失败了main_contextwork_contextwork_context

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <sys/time.h>
#include <unistd.h>

#define _XOPEN_SOURCE 600
#include "ucontext.h"


static ucontext_t main_context;
static ucontext_t work_context[3];  // version 2: from ucontext_t to an array

static void counter()
{
    for (int c = 0; ; c++) {
        fprintf(stderr, "c = %d\n", c);
        sleep(5);  // avoid busy loop
    }
}

static ucontext_t* make_context1(ucontext_t *ucp,  void (*func)())
{
    getcontext(ucp);
    sigemptyset(&ucp->uc_sigmask);

    void *sp = malloc(SIGSTKSZ);
    if (sp == NULL) {
        fprintf(stderr, "malloc failed\n");
        exit(-1);
    }
    ucp->uc_stack = (stack_t) { .ss_sp = sp, .ss_size = SIGSTKSZ, .ss_flags = 0 };
    ucp->uc_link = &main_context;
    
    makecontext(ucp, func, 0);
    return ucp;
}

int main() {
    printf("start\n");
    make_context1(work_context, counter);
    make_context1(work_context+1, counter);  // added in version 2
    make_context1(work_context+2, counter);  // added in version 2

    swapcontext(&main_context, work_context);
    printf("main exit\n");
    return 0;
}
4

2 回答 2

0

好吧,这很简单 -SIGSTKSZ对于printf. 增加它。把它翻四倍。

移动#define _XOPEN_SOURCE 600到文件的顶部。见man feature_test_macros

添加#include <signal.h>sigemptyset. 更改"ucontext.h"<ucontext.h>- 这是一个标准标题。

于 2021-04-15T01:45:15.910 回答
0

出于某种原因,如果我更改这两行代码,代码运行不会崩溃:

ucontext_t main_context;
ucontext_t work_context;

对此:

static ucontext_t main_context;
static ucontext_t work_context;

我确信对此有一个很好的解释,但我不知道它是什么:(

于 2021-04-14T03:16:07.993 回答