挑战性任务 shell 求助

Nadleeh
🔖︎ 9 订阅
👍︎ 4 点赞

image.png 这个任务需要我们拿到command的返回值,然而我们的command遇到问题直接user_panic了,出错时的返回值不详。
因此,我们目前的指令似乎没有能返回错误码的,需要我们修改所有command以使其能返回错误码吗,如果是,我们应该返回什么错误码

回复主题帖

戴波(助教)
👍︎ 0 点赞

是的,所有command都需要能够返回值表示是否成功执行,但是并不对返回的错误码做要求,也即如果成功则返回0,否则返回非0值即可。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

那这样的话,我能直接删了原来的panic改成print加return r吗
我正试图直接从command进程的v0寄存器取出返回结果然后ipc发回父进程,这样有可行性吗


戴波(助教) 回复 Nadleeh
👍︎ 0 点赞

那这样的话,我能直接删了原来的panic改成print加return r吗

可以的。

我正试图直接从command进程的v0寄存器取出返回结果然后ipc发回父进程,这样有可行性吗

这也是可以的,可以在exit函数中传入返回值参数,然后通过ipc返回给父进程再结束。


严少泽 回复 戴波(助教)
👍︎ 1 点赞

请问评测的时候会检查user_panic输出的panic at吗


戴波(助教) 回复 严少泽
👍︎ 0 点赞

不会。


戴波(助教) 回复 严少泽
👍︎ 0 点赞

需要补充说明下,指导书中对于新增的指令中有错误输出的要求,比如touchmkdir等指令,其他MOS原有指令并不需要考虑错误输出,如有问题欢迎再次提出。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

image.png 现在还是在实现这个exit返回值的功能,我和同学都遇到了同一个症状的bug:管道符右侧指令输入错误会整个MOS都卡死,左侧输错和单条指令输错均不会。

我的实现是在exit里进程destroy前用ipc_send发同步消息,在wait()函数里用ipc_recv接收消息。

4005号进程是ls指令的子shell,4086号进程是ca(错误指令)的shell,上图waiting处是debug信息(见下),但是令人疑惑的是完全不知道4005号进程为什么会在开始执行ls前发生wait以及没有收到消息他为什么会继续向下运行到红框处。 image.png


戴波(助教) 回复 Nadleeh
👍︎ 2 点赞

4005号进程为什么会在开始执行ls前发生wait以及没有收到消息他为什么会继续向下运行到红框处。

你的实现为:

image.png

4005 waiting表达的应该是有进程在等待4005进程发送消息。然后后面的4005 spawn ls: started应该才是4005进程的spawn输出。

管道符右侧指令输入错误会整个MOS都卡死,左侧输错和单条指令输错均不会。

可以考虑一下进程在wait和exit使用ipc通信,进程与fs进程也是使用ipc进行通信,ipc对进程状态的设置对进程调度队列的影响以及进程调度队列的执行。

需要注意fs进程运行一个时间片其实最多只能解决一个请求。

这里卡死的原因应该是4806子进程结束返回的1到了4005进程spwan函数调用open函数进而调用fsipc_map函数的ipc_recv,导致open返回1,可是spawn中如果open返回值小于0才会返回该返回值,所以会使用readn读取二进制文件ls.b的内容,但是由于4806进程使用ipc_send时,并没有使用srcva映射到4005进程在fsipc_map中设置的dstva,导致readn函数此时访问空地址,从而卡死。

由于没有直接代码,我猜测原因是这样,如有疑问或者错误欢迎提出。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

万分感谢,确实是收发消息的问题
对终止消息采用了一些新的ipc设计后彻底解决
ヾ(≧▽≦*)o


如翚斯飞 回复 戴波(助教)
👍︎ 0 点赞

请问挑战性任务的“自动化评测”是如何进行的,以及我们在最终提交前能否看到自动化评测的结果?


戴波(助教) 回复 如翚斯飞
👍︎ 1 点赞

类似于课下的测试,大概会在一周之后开放。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

请问现在开放的shell自动测试的形式是怎样的。
我已实现前两个测试点要求的内容(条件执行与三个新增指令)。
自己验证了&&与||的逻辑基本没有问题,为何所有点都无法通过测试呢? (手搓测试见下)
image.png
(无论是带不带那些调试信息(destroying env等)均无法通过任何测试点
ps:我修改了init.c,使得启动可以通过make && make run,应该无伤大雅。


戴波(助教) 回复 Nadleeh
👍︎ 0 点赞

评测的方式与之前lab6 shell的课下测试相同;测试中可能会出现文件名中不带.b的可执行文件,可以检查下自己这一部分的实现。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

应该不是这个问题,上面自测的图里用的就都是没有.b的指令
另外,能确保1,2测试点不依赖3,4,5吗


戴波(助教) 回复 Nadleeh
👍︎ 0 点赞

如果使用的可执行文件是事先就编译好放在文件系统中,并且本身就不带.b文件后缀名,这种情况也是存在的,不能单纯地在spawn函数中检测.b并添加后缀。 1,2测试点应该是不依赖后续测试点的。


严少泽 回复 戴波(助教)
👍︎ 0 点赞

请问助教如果可执行文件不带.b的话,这样该如何实现呢?目前没太想到合适的办法.

而且指令名不是固定在include.mk里的嘛


戴波(助教) 回复 严少泽
👍︎ 0 点赞

对于.b后缀的测试,评测会将直接编译好的不带.b后缀的文件放入文件系统,而非通过mos的编译生成。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

我改成了先尝试读取原指令,如果不行再读取拼接了.b的指令,依然无法通过任何测试点,感到十分疑惑


戴波(助教) 回复 Nadleeh
👍︎ 0 点赞

可以尝试在编译时开启优化试一下:make MOS_PROFILE=release,检查下编译时出现的warning。


Nadleeh 回复 戴波(助教)
👍︎ 0 点赞

警告已经全部消除,但是编译器开启O2时会发生完全无法预测的错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int spawn(char *prog, char **argv) {
// Step 1: Open the file 'prog' (the path of the program).
// Return the error if 'open' fails.
int fd;
int len = strlen(prog);
if ((fd = open(prog, O_RDONLY)) < 0) {
printf("%s\n", prog);
if ((*(prog + len - 2) != '.' || *(prog + len - 1) != 'b') && len < MAXNAMELEN - 2) {
char program[MAXNAMELEN];
strcpy(program, prog);
program[len] = '.';
program[len + 1] = 'b';
program[len + 2] = 0;
prog = program;
}
printf("%s\n", prog);
if ((fd = open(prog, O_RDONLY)) < 0) {
return fd;
}
}
开启优化前能正常运行,开启后输入ls,两处printf均输出ls,执行错误
但是如果给prog = program那一行后面加上一行print program 则能执行正确

官方测试时开启的o2乱序执行真的没有问题吗

戴波(助教) 回复 Nadleeh
👍︎ 2 点赞

其实可以发现char program[MAXNAMLEN]这一部分栈空间的作用域在if(fd=open ...)那个括号里面,所以当出了那个作用域的时候其实那部分内存其实就被释放掉了,这个时候prog指向program再使用的话就成了野指针,可能会出现意料之外的错误,可以尝试把char program[MAXNAMELEN]放在外面。


Nadleeh 回复 戴波(助教)
👍︎ 1 点赞

感谢,修改过后第二三个点能对了,但是第一个点仍全0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ true || echo 1 && echo 2 || false && echo 3
[00007805] destroying 00007805
[00007805] free env 00007805
i am killed ...
[00007004] destroying 00007004
[00007004] free env 00007004
i am killed ...
2
[00008805] destroying 00008805
[00008805] free env 00008805
i am killed ...
[00008004] destroying 00008004
[00008004] free env 00008004
i am killed ...
3
[00009805] destroying 00009805
[00009805] free env 00009805
i am killed ...
[00009004] destroying 00009004
[00009004] free env 00009004
i am killed ...

自测结果如上,似乎并无问题,我实在找不到问题()>﹏<


严少泽 回复 Nadleeh
👍︎ 0 点赞

+1


zyt 回复 Nadleeh
👍︎ 0 点赞

+1


RooKie_xxx 回复 戴波(助教)
👍︎ 1 点赞

想请问助教各个测试点间的依赖关系是怎么样的


戴波(助教) 回复 RooKie_xxx
👍︎ 0 点赞

image.png 可以参考下这个,评测基本都对应各自说明的内容。


solor-wind 回复 戴波(助教)
👍︎ 1 点赞

请问第一个测试点对touch等自己实现的指令的返回值、实现分号隔开的多个指令有要求吗?


zyt 回复 solor-wind
👍︎ 1 点赞

同学你好,我的理解是第一个测试点不会出现touch等自己实现的指令。


RooKie_xxx 回复 戴波(助教)
👍︎ 1 点赞

请问助教 image.png 但是评测所给的makefile里面并没有history.b,这是不是意味着正确实现为history.b的办法不可行呢 image.png


戴波(助教) 回复 RooKie_xxx
👍︎ 0 点赞

已经在指导书中将history.b指令的描述改为必须实现为内建指令,可以刷新下界面查看。

0%