I am trying to call getcontext into another function (instead of calling it directly into main) in order to copy the thread's stack and restore it later. This code should print repeatedly, but it won't work once the function that called getcontext returns.
Is there a way to circumvent this limitation and call getcontext in another function (other than inline macros)?
#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>
ucontext_t context;
void set_context() {
setcontext(&context);
}
void get_context() {
getcontext(&context);
}
int main() {
get_context();
puts("Hello world");
sleep(1);
set_context();
return 0;
}
getcontext
saves only the machine register state at the point of the call. It does not store the content of stack memory at that position. When you call setcontext
then it does jump executing the code from get_context
but the very next instruction then pops the return address of the set_context
call:
#include <stdio.h>
#include <ucontext.h>
#include <unistd.h>
ucontext_t context;
void set_context() {
puts("Calling setcontext");
setcontext(&context);
puts("Returned from setcontext");
}
void get_context() {
puts("Calling getcontext");
getcontext(&context);
puts("Returned from getcontext");
}
int main() {
get_context();
puts("Hello world");
sleep(1);
set_context();
return 0;
}
Output:
Calling getcontext
Returned from getcontext
Hello world
Calling setcontext
Returned from getcontext
What you want to do - continuations - could be done this way in principle, but they just wouldn't work in practice... I.e. no, you will never get what you want to do to work with a random C program between these two calls. Furthermore, it was only by accident that your test didn't result in a crash... (both setcontext and getcontext happened in places where the stack top was located at the same address).