【问题标题】:In this case, isn't the process always unable to be killed?在这种情况下,进程不是总是无法被杀死吗?
【发布时间】:2021-08-31 23:24:50
【问题描述】:

问题涉及到比较零散的代码,这里我给出主要代码。

完整代码:syscall.c

static uint64
argraw(int n)
{
  struct proc *p = myproc();
  switch (n) {
  case 0:
    return p->tf->a0;
  case 1:
    return p->tf->a1;
  case 2:
    return p->tf->a2;
  case 3:
    return p->tf->a3;
  case 4:
    return p->tf->a4;
  case 5:
    return p->tf->a5;
  }
  panic("argraw");
  return -1;
}

// Fetch the nth 32-bit system call argument.
int
argint(int n, int *ip)
{
  *ip = argraw(n);
  return 0;
}

....
....

static uint64 (*syscalls[])(void) = {
[SYS_fork]    sys_fork,
[SYS_exit]    sys_exit,
[SYS_wait]    sys_wait,
[SYS_pipe]    sys_pipe,
[SYS_read]    sys_read,
[SYS_kill]    sys_kill,
[SYS_exec]    sys_exec,
[SYS_fstat]   sys_fstat,
[SYS_chdir]   sys_chdir,
[SYS_dup]     sys_dup,
[SYS_getpid]  sys_getpid,
[SYS_sbrk]    sys_sbrk,
[SYS_sleep]   sys_sleep,
[SYS_uptime]  sys_uptime,
[SYS_open]    sys_open,
[SYS_write]   sys_write,
[SYS_mknod]   sys_mknod,
[SYS_unlink]  sys_unlink,
[SYS_link]    sys_link,
[SYS_mkdir]   sys_mkdir,
[SYS_close]   sys_close,
[SYS_ntas]    sys_ntas,
};

....
....

void
syscall(void)
{
  int num;
  struct proc *p = myproc();

  num = p->tf->a7;
  if(num > 0 && num < NELEM(syscalls) && syscalls[num]) {
    p->tf->a0 = syscalls[num]();              // question here
  } else {
    printf("%d %s: unknown sys call %d\n",
            p->pid, p->name, num);
    p->tf->a0 = -1;
  }
}

完整代码:sysproc.c

uint64
sys_exit(void)
{
  int n;
  if(argint(0, &n) < 0)
    return -1;
  exit(n);
  return 0;  // not reached
}

uint64
sys_kill(void)
{
  int pid;

  if(argint(0, &pid) < 0)
    return -1;
  return kill(pid);
}

完整代码:proc.c

int
kill(int pid)
{
  struct proc *p;

  for(p = proc; p < &proc[NPROC]; p++){
    acquire(&p->lock);
    if(p->pid == pid){
      p->killed = 1;
      if(p->state == SLEEPING){
        // Wake process from sleep().
        p->state = RUNNABLE;
      }
      release(&p->lock);
      return 0;
    }
    release(&p->lock);
  }
  return -1;
}

对于p-&gt;tf-&gt;a0 = syscalls[num]();(在syscall.c中),调用这行代码后,p-&gt;tf-&gt;a0的值会发生变化, 如您所见,sys_exit() 返回的是 0 或 -1,sys_fork() 可能返回 pid 或 -1(函数 sys_fork() 中的fork())。 这样它存储的值可能不再是pid,而是其他函数的返回值。

我的问题: 综上所述,在调用sys_kill()时,函数中argint()得到的值可能不是进程的pid, 所以kill()的参数可能不是进程的pid。 这种情况下,进程不是一直杀不掉吗?

【问题讨论】:

  • 对于kill()exit(),返回的内容似乎相对无关——进程已经被通知结束(因为系统调用首先完成)。重要的是保持进程运行的任何其他“正常”系统调用(你没有显示)是否以扰乱此机制的方式修改 p-&gt;tf-&gt;a0

标签: c operating-system xv6


【解决方案1】:

正如您所指出的,有问题的行是: p-&gt;tf-&gt;a0 = syscalls[num]();

当编译器看到这一行时,会发生什么?可以分两步分解:

uint64 ret;

ret = syscalls[num]();

p->tf->a0 = ret;

换句话说,p-&gt;tf-&gt;a0 在被sys_kill 使用之后 被更新

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 2011-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多