sigaction的bug在哪里?

RyotoTannhauser
🔖︎ 8 订阅
👍︎ 2 点赞

我在sigaction的测评中通过了1、2、3、4、5五个测试点,但是在第6个点出现了Something unexpected ocurred这样的结果,请问这是什么错误呢?

求求助教来一些复杂的样例QAQ

回复主题帖

__cxc__
👍︎ 0 点赞

同样是这个info,已经搓了好几组了还是卡在这...


__cxc__ 回复 __cxc__
👍︎ 0 点赞

现在4没问题了,卡在6了


RyotoTannhauser 回复 __cxc__
👍︎ 0 点赞

修改了什么地方呢,我这面epc+4后还是没有过QWQ


__cxc__ 回复 RyotoTannhauser
👍︎ 2 点赞

试试这个,有关SIGKILL的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <lib.h>
#include <signal.h>

void sigchld_handler(int sig) {
    debugf("capture SIGCHLD signal.\n");
    debugf("shouldn't see this.\n");
}

int main() {
    struct sigaction sa;
    sa.sa_handler = sigchld_handler;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGCHLD, &sa, NULL);
    u_int pid = syscall_getenvid();
    if (fork() == 0) {
        debugf("send kill to %x\n", pid);
        kill(pid, SIGKILL);
        exit();
    }
    while (1);
   return 0;
}

正确结果应该是不进入CHLD的handler,直接结束


RyotoTannhauser 回复 __cxc__
👍︎ 0 点赞

现在我的4也没问题了

但这个6我全错,,,bug也太难想了QUQ


lhp 回复 RyotoTannhauser
👍︎ 1 点赞

同学可以请教一下是什么地方有问题吗?


RyotoTannhauser 回复 lhp
👍︎ 2 点赞

我是考虑到有些信号在没有注册(调用sigaction)情况下就会发送,所以在do_signal中多了一些判断条件。

有下面这个例子:

1
2
3
4
5
6
7
8
9
10
#include <lib.h>

int main()
{
debugf("sending 5 to myself\n");
kill(0, 5);
debugf("the program will run as usual\n");

return 0;
}

这个程序应该是会正常结束(我最后会输出panic at sched),而不是因为没有注册而发生一些异常的事情(比如自己定义的panic)。

如果将5修改成了SIGSEGV, SIGILL, SIGINT, SIGKILL,程序不会打印the program will run as usual


__cxc__ 回复 RyotoTannhauser
👍︎ 2 点赞

我现在和你一样。我觉得应该有更强更综合的样例来说明这个任务实现上的限制,现在的指导写的太模糊了。。

回复主题帖

fatiger
👍︎ 1 点赞

我从6/18到16/18是在默认处理为忽略时候对tf->epc0+4

回复主题帖

lhp
👍︎ 0 点赞

我的测试点六错误信息是WA: sigaction error,想问问同学们有没有出现过类似的错误


RyotoTannhauser 回复 lhp
👍︎ 1 点赞

我之前也出现过,是int sigaction(int signum, const struct sigaction *newact, struct sigaction *oldact)oldact的设置不对,应该保存signum对应的那个掩码(我之前是保存了当前进程屏蔽的掩码)


lhp 回复 RyotoTannhauser
👍︎ 0 点赞

我的这里好像没问题,不过修改了注册时就屏蔽自己后,测试点6过了一个,报错信息也变成了unexpected error

1
2
3
4
sys_sigaction
······
//curenv->env_sigs[signum].sa_mask.sig |= (1 << (signum - 1));
curenv->env_sigs[signum].sa_mask.sig &= (~(1 << 8));

lhp 回复 lhp
👍︎ 0 点赞

我的6/18->18/18

1
2
3
4
5
6
7
8
#include <lib.h>
int main() {
int* ptr = (int*)0x0;
debugf("Accessing invalid memory address...\n");
int val = *ptr;
debugf("If you see this on your screen, it means that the signal is not handled correctly.\n");
return 0;
}

在未进行任何注册的情况下也应该能默认处理

回复主题帖

__cxc__
👍︎ 7 点赞

我过了
一个很关键的修改是sigset系列操作中对输入是否为空更严格的检查,这个小改动能决定是0/6还是6/6.
所以我推测test6是有更极端的参数,比如给set传入NULL这种,导致如果不做检查就会0/6。不知道是否有帮助。


RyotoTannhauser 回复 __cxc__
👍︎ 1 点赞

神仙,太谢谢你辣~


siven 回复 __cxc__
👍︎ 1 点赞


MC的大虾1472 回复 __cxc__
👍︎ 0 点赞

cp0_epc + 4的问题现在同学是怎么解决的呢?


__cxc__ 回复 MC的大虾1472
👍︎ 3 点赞

就是只有sigsys才+4,不过这个我做过实验,是不是只有sigsys才+4不影响正确性


__cxc__ 回复 __cxc__
👍︎ 3 点赞

另外,如果输入为null也不要加多余的panic,要么忽略要么返回-1


lhp 回复 __cxc__
👍︎ 0 点赞

请问对于SIGKILL,需要让其他信号在注册时或者修改掩码时不能屏蔽SIGKILL吗,还是说在给进程添加信号时检测到进程存在等待的SIGKILL时不发送就可以了呢?


__cxc__ 回复 lhp
👍︎ 1 点赞

我应该是做了前者

0%