Pintos项目2参数传递实现后运行echo x触发页错误及段错误
问题排查结果
1. GDB调试方法错误
你直接对kernel.o执行run是完全错误的,kernel.o只是编译生成的可重定位目标文件,不是可以直接在宿主机运行的可执行程序。Pintos内核运行在模拟器之上,正确的调试方法是先启动带调试端口的模拟器实例,再用gdb连接远程调试端口,你看到的SIGSEGV和你的实际业务代码无关,是调试方法不对导致的。
2. 核心错误:argc计数溢出
你的start_process中参数计数逻辑存在严重错误:
argv[0] = strtok_r(fn_copy, " ", &save_ptr); while(argv[argc++] != NULL){ argv[argc] = strtok_r(NULL, " ", &save_ptr); }
以你运行的echo x为例:
- 第一次判断
argv[0]非空,argc自增为1,读取argv[1] = "x" - 第二次判断
argv[1]非空,argc自增为2,读取argv[2] = NULL - 第三次判断
argv[2]为空,循环终止,此时argc值为3
但实际echo x的有效参数个数应为2(程序名echo加参数x),你多算了1位。后续construct_esp中循环到i = argc-1 = 2时,访问argv[2]的NULL指针调用strlen()直接触发内核页错误,进程直接终止,根本没有执行到echo程序的write系统调用,所以你的syscall_handler中的打印自然不会输出,你运行日志里的Exception: 1 page faults就是这里触发的。
3. 其他隐患
你在process_execute中直接对const char *file_name执行strtok_r操作,strtok_r会修改原字符串内容,修改const修饰的字符串属于未定义行为,你应该用提前申请的fn_copy来做参数分割,不要修改原输入字符串。
修复方案
- 修正参数计数逻辑:
argc = 0; argv[argc] = strtok_r(fn_copy, " ", &save_ptr); while(argv[argc] != NULL) { argc++; argv[argc] = strtok_r(NULL, " ", &save_ptr); }
修正后echo x的argc值为2,符合预期。
2. 修改process_execute的参数分割逻辑,用fn_copy替代原file_name做分割。
3. 按照Pintos官方文档的远程调试方法调试内核,不要直接运行kernel.o。
内容的提问来源于stack exchange,提问作者안태찬
相关产品推荐
相关产品推荐

