I'm trying to build an operating system project which gets the current thread's context and serialize, send it over the network to another machine and pick up where the thread left off and continue. (So-called thread-migrator).
I managed to finish it in Linux but when I run in a real environment I always get segmentation fault but it worked under gdb.
It may be due to the address randomization problem because when I turn on the randomization in gdb it shows that there's segmentation fault in setcontext().
But I just don't get it because the text section won't get randomized(and I checked the REG_RIP value in ucontext.mcontext.greps, they're the same each time). Then what could possibly be the reason that the address randomization crashes it? The stack would be set directly by the ucontext, which I don't think the randomization will be a problem.
My server code looks like this.
bool_t migrate_1_svc(rpc_ucontext *context, void *res, struct svc_req *req)
{
printf("Server received.\n");
ucontext_t cont;
// initialize the context
getcontext(&cont);
cont.uc_flags = context->uc_flags;
// ucontext.stack_t
cont.uc_stack.ss_flags = context->uc_stack.ss_flags;
cont.uc_stack.ss_sp = context->uc_stack.ss_sp.ss_sp_val;
cont.uc_stack.ss_size = context->uc_stack.ss_sp.ss_sp_len;
// ucontext.mcontext_t
memcpy(cont.uc_mcontext.__reserved1, context->uc_mcontext.__reserved1, sizeof(cont.uc_mcontext.__reserved1));
cont.uc_mcontext.fpregs = (struct _libc_fpstate *)malloc(sizeof(struct _libc_fpstate));
memcpy(cont.uc_mcontext.fpregs, &context->uc_mcontext.fpregs, sizeof(struct _libc_fpstate));
memcpy(cont.uc_mcontext.gregs, context->uc_mcontext.gregs, sizeof(gregset_t));
memcpy(&cont.uc_sigmask, &context->uc_sigmask, sizeof(__sigset_t));
memcpy(&cont.__fpregs_mem, &context->__fpregs_mem, sizeof(struct _libc_fpstate));
printf("Setting the context.\n");
ucontext_t my_context;
getcontext(&my_context);
cont.uc_link = &my_context;
setcontext(&cont);
return true;
}