XV6中自定义getprocinfo系统调用报错,请求排查解决
XV6 自定义
getprocinfo系统调用失败排查与修复 问题重现
在XV6中实现了返回当前进程PID、状态的系统调用getprocinfo,调用时始终返回-1,输出提示Error: Not able to access process information!。
内核态实现(sysproc.c)
uint64 sys_getprocinfo(struct proc* user_pi) { struct proc *curproc = myproc(); struct proc pi; acquire(&curproc->lock); pi.pid = curproc->pid; pi.state = curproc->state; release(&curproc->lock); if(copyout(curproc->pagetable, (uint64)user_pi, (char*)&pi, sizeof(pi)) < 0) return -1; return 0; }
用户态代码(user/getproc.c)
#include "user.h" //#include "kernel/types.h" //blueprint for proc info strukturen struct proc { int pid; int state; //evt annet? }; //state nr tilsvarer nr i array her: //enum procstate { UNUSED, USED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE} int main(void) { //info blir av typen proc info over struct proc pi; //kaller syscallet med &info som argument int result = getprocinfo(&pi); if (result < 0) { printf("Error: Not able to access process information! "); } else { printf("Process ID: %d, Process state: %d ", pi.pid, pi.state); } exit(0); }
问题排查
系统调用参数传递逻辑错误
XV6的sys_*系列函数不能直接接收用户态指针作为参数,必须通过argaddr等内核API从用户态栈中读取参数地址。当前代码直接将用户指针传入sys_getprocinfo,内核无法正确解析用户态地址空间,导致后续copyout失败。内核与用户态结构体大小不匹配
内核中的struct proc包含大量额外字段(如页表、锁、上下文等),而用户态自定义的struct proc仅包含pid和state。copyout时使用sizeof(struct proc)(内核中完整结构体大小)进行拷贝,会导致越界访问用户态内存,触发错误。字符串换行符未转义
用户态代码中printf的字符串直接使用换行而不是\n,会导致编译错误或输出异常。
修复方案
修复后的内核态代码(sysproc.c)
uint64 sys_getprocinfo(void) { struct proc *curproc = myproc(); // 定义与用户态完全一致的结构体,避免大小不匹配 struct { int pid; int state; } pi; uint64 user_buf; // 从用户态栈中读取第一个参数:用户态缓冲区地址 if(argaddr(0, &user_buf) < 0) return -1; acquire(&curproc->lock); pi.pid = curproc->pid; pi.state = curproc->state; release(&curproc->lock); // 使用用户态结构体的大小进行拷贝 if(copyout(curproc->pagetable, user_buf, (char*)&pi, sizeof(pi)) < 0) return -1; return 0; }
修复后的用户态代码(user/getproc.c)
#include "user.h" // 与内核中用于拷贝的结构体保持一致 struct proc_info { int pid; int state; }; enum procstate { UNUSED, USED, SLEEPING, RUNNABLE, RUNNING, ZOMBIE}; int main(void) { struct proc_info pi; int result = getprocinfo(&pi); if (result < 0) { printf("Error: Not able to access process information!\n"); } else { printf("Process ID: %d, Process state: %d\n", pi.pid, pi.state); } exit(0); }
额外必做配置
- 在
syscall.h中添加系统调用编号:#define SYS_getprocinfo 22(替换为未占用的编号) - 在
syscall.c的syscalls数组中添加条目:[SYS_getprocinfo] sys_getprocinfo, - 在
user.h中添加函数声明:int getprocinfo(struct proc_info*);
内容的提问来源于stack exchange,提问作者Sondre
相关产品推荐
相关产品推荐

