I've written a simple program, use ucontext
library. However, a signal SIGSEGV (address boundary error) occurred. The running env is MacOS. I do not know what's wrong I made?
Updated Here: Version 2
As @Jeremy suggest, we could use static on main_context
and work_context
. However, if we change work_context
to an array, it still failed
#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;
}
Well, that's simple -
SIGSTKSZ
is too small of a stack forprintf
. Increase it. Quadruple it.Move
#define _XOPEN_SOURCE 600
on top of the file. Seeman feature_test_macros
.Add
#include <signal.h>
forsigemptyset
. Change"ucontext.h"
into<ucontext.h>
- it's a standard header.