c - 在这种情况下,进程不是总是无法被杀死吗?
问题描述
问题涉及到比较零散的代码,这里我给出主要代码。
完整代码: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->tf->a0 = syscalls[num]();
(在syscall.c中),调用这行代码后,值p->tf->a0
会发生变化,可以看到,sys_exit()
返回的是0或-1,sys_fork()
可能返回pid或-1(fork()
在函数中sys_fork()
)。这样它存储的值可能不再是pid
,而是其他函数的返回值。
我的问题:根据上述,当sys_kill()
被调用时,argint()
函数中获取的值可能不是pid
进程的,所以kill()的参数可能不是进程的pid。在这种情况下,进程不是总是无法被杀死吗?
解决方案
正如您指出的那样,有问题的行是:
p->tf->a0 = syscalls[num]();
当编译器看到这一行时,会发生什么?您可以分两步分解它:
uint64 ret;
ret = syscalls[num]();
p->tf->a0 = ret;
换句话说,在被使用后p->tf->a0
更新sys_kill
推荐阅读
- python-3.x - 一次访问 RDD 中的 200 个文件 pyspark
- operators - 数学等价于双右移和 AND 运算符?
- python - 如何修复 TypeError:不支持的操作数类型?
- django-crispy-forms - 如何将所有剩余的模型字段添加到 django 清晰的表单布局中?
- css - 当我访问某些网址时,字体真棒图标不显示
- laravel - Laravel 重定向和更改 URL
- webpack - Webpack html-webpack-plugin 不工作
- python - 给定一个数组;我需要子数组;其元素的 XOR 值等于某个给定值
- regex - 谷歌表格语法问题
- sql-server - SSIS 将 yyyy-mm-dd hh:mm 转换为 ISO8601