1

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;
}
Jacky1205
  • 3,273
  • 3
  • 22
  • 44

2 Answers2

0

For some reason the code runs without crashing if I change these two lines:

ucontext_t main_context;
ucontext_t work_context;

to this:

static ucontext_t main_context;
static ucontext_t work_context;

I'm sure there is a good explanation for this, but I don't know what it is :(

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Hi, I changed the type of `work_context` to an array, and it failed again even if **static** is used. – Jacky1205 Apr 14 '21 at 04:51
  • I did get a bunch of `warning: 'swapcontext' is deprecated: first deprecated in macOS 10.6` type of warnings when I compiled the code; it might be that MacOS's support for this API isn't quite up to snuff in current MacOS/X versions. – Jeremy Friesner Apr 14 '21 at 04:56
0

Well, that's simple - SIGSTKSZ is too small of a stack for printf. Increase it. Quadruple it.

Move #define _XOPEN_SOURCE 600 on top of the file. See man feature_test_macros.

Add #include <signal.h> for sigemptyset. Change "ucontext.h" into <ucontext.h>- it's a standard header.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • `SIGSTKSZ` is 131072, 128K, still so small? `#define SIGSTKSZ 131072 /* (128K)recommended stack size */` – Jacky1205 Apr 15 '21 at 02:19