我正在尝试构建一个操作系统项目,该项目获取当前线程的上下文并进行序列化,通过网络将其发送到另一台机器,然后从线程停止的地方继续执行。(所谓的线程迁移器)。
我设法在 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;
}