gpt4 book ai didi

c - SIGSEGV 的 sig 处理问题

转载 作者:行者123 更新时间:2023-11-30 15:58:14 33 4
gpt4 key购买 nike

我创建了一个信号处理程序,以便在发送 SIGSEGV 时调用。我使用 C 语言编写程序,还使用 ​​Linux 和 intel x86 处理器。在 sig 处理程序中,看起来通过 siginfo_t 结构传入的 si_addr 被赋予值 0,而不是导致问题的指令地址的值。我在 sigaction 中设置了 SIG_INFO 标志,所以我不知道为什么会发生这种情况。

这里是一些示例代码:

int main(){
mprotect(..., PROC_READ | PROC_WRITE /* | PROC_EXEC */); //cannot execute page

someMethodOnRestrictedPage();
//do some stuff
}

void init_sighandler(void) {

//initialize the sigaction so that sig handler is called when a SIGSEGV is thrown
struct sigaction * action;

action = (struct sigaction *) malloc(sizeof(struct sigaction));

action->sa_sigaction = sighandler;
sigemptyset (&action->sa_mask);

action->sa_flags = 0;

sigaddset(&action->sa_mask, SA_SIGINFO);
sigaddset(&action->sa_mask, SA_RESTART);

sigaction(SIGSEGV, action, NULL);
}

void sighandler(int sig, siginfo_t *siginfo, void *ucp){
printf("%x\n", siginfo->si_addr); // prints out 0
}

最佳答案

您的.sa_flagsSA_SIGINFO位已清除。

引用http://pubs.opengroup.org/onlinepubs/7908799/xsh/sigaction.html ,

SA_SIGINFO

如果清除并且信号被捕获,则信号捕获函数将输入为:

void func(int signo);

哪里signo是信号捕获函数的唯一参数。在这种情况下 sa_handler必须使用成员来描述信号捕获功能,并且应用程序不得修改 sa_sigaction成员(member)。

如果SA_SIGINFO设置并捕获信号,则信号捕获函数将输入为:

void func(int signo, siginfo_t *info, void *context);

其中两个附加参数被传递给信号捕获函数。第二个参数将指向 siginfo_t 类型的对象。解释产生信号的原因;第三个参数可以转换为指向 ucontext_t 类型的对象的指针引用信号传递时被中断的接收进程的上下文。在这种情况下 sa_sigaction必须使用成员来描述信号捕获功能,并且应用程序不得修改 sa_handler成员(member)。

si_signo成员包含系统生成的信号号。

si_errno成员可能包含依赖于实现的附加错误信息;如果非零,则它包含一个错误号,用于标识导致生成信号的条件。

si_code成员包含标识信号原因的代码。如果 si_code 的值小于或等于 0,则信号由进程生成且 si_pidsi_uid分别表示发送者的进程ID和真实用户ID。 <signal.h> header 描述包含有关 siginfo_t 元素的信号特定内容的信息。类型。

--引用结束

所以 sigaction 使用 .sa_handler如果该位被清除,并且 .sa_sigaction如果该位已设置。

所以你有未定义的行为,因为你正在阅读不成文的论点。

设置.sa_flags = SA_SIGINFO | ...纠正问题。

关于c - SIGSEGV 的 sig 处理问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9898491/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com