我正在尝试构建一个操作系统项目,该项目获取当前线程的上下文并进行序列化,通过网络将其发送到另一台机器并获取线程停止并继续的位置。 (所谓的线程迁移器)。
我设法在Linux中完成它,但是当我在真实环境中运行时,我总是遇到分段错误,但它在gdb下工作。
这可能是由于地址随机化问题,因为当我打开gdb中的随机化时,它表明setcontext()中存在分段错误。
但我只是不明白,因为文本部分不会随机化(我检查了ucontext.mcontext.greps中的REG_RIP值,每次都是相同的)。那可能是地址随机化崩溃的原因呢?堆栈将由ucontext直接设置,我认为随机化不会成为问题。
我的服务器代码如下所示。
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;
}