1

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

我设法在 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;
}
4

0 回答 0