我尝试使用一个异常处理器来捕捉错误的内存访问,但我不完全确定如何去做。我尝试用sigaction注册它,但我的处理器没有触发。
旧代码
#include <stdio.h>
#include <signal.h>
void handler(int sig)
{
//exception should land here
printf("caught exception");
}
int main(int argc, const char * argv[]) {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
sigemptyset(&act.sa_mask);
act.sa_handler = handler;
if(sigaction(SIGSEGV, &act, NULL)==-1){
printf("Could not register handler");
}else{
printf("handler registered\n");
}
*(int*)0 = 0;//throw exception
return 0;
}
一旦进入处理程序,我如何读取线程上下文寄存器?我也在MacOS上,所以我不确定是否有任何操作系统特定的实现。
编辑:新代码
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#define _XOPEN_SOURCE 600
#include <ucontext.h>
void handler(int sig, siginfo_t *info, void *uc)
{
(void) sig;
write (STDOUT_FILENO, "Caught exception\n", 17);
struct ucontext* mc = (struct ucontext*)uc;
}
int main(int argc, const char * argv[]) {
struct sigaction act;
act.sa_flags = SA_SIGINFO;
sigemptyset(&act.sa_mask);
act.sa_handler = handler;
if(sigaction(SIGSEGV, &act, NULL)==-1){
printf("Could not register handler");
}else{
printf("handler registered\n");
}
raise (SIGSEGV);
return 0;
}
当我包含ucontext.h
时,我的编译器遇到了这个错误
#else /* !_XOPEN_SOURCE */
#error The deprecated ucontext routines require _XOPEN_SOURCE to be defined
#endif /* _XOPEN_SOURCE */
我通过定义_XOPEN_SOURCE解决了这个问题,但是编译器仍然不知道ucontext是什么,因为我没有得到任何智能..我可能必须自己定义这个结构
编辑:因为我是在M1上,所以我是从ARM而不是x86_64编译的,ucontext和mcontext都必须使用64位变体。
2条答案
按热度按时间3duebb1j1#
不要依赖它,而是使用
raise()
向调用进程发送一个信号:因此代码变为:
stderr
:**无论是C标准还是POSIX标准都没有指定
printf()
是异步信号安全的,这意味着它不能在信号处理程序内部被安全地调用。不过,POSIX标准确实指定
write()
是异步信号安全的,所以printf()
应该用它来代替。handler()
的声明不正确:**如果设置了
SA_SIGINFO
,则void handler(int sig)
不正确:"如果设置了SA_SIGINFO
,并且捕获了信号,则信号捕获函数应输入为:void func(int signo, siginfo_t *info, void *context);
"-@安德鲁·亨勒handler()
分配给正确的成员:**sigaction结构定义如下:
使用
SA_SIGINFO
标志时,需要将信号处理函数分配给.sa_sigaction
,而不是.sa_handler
。ru9i0ody2#
您的第一个问题似乎已经得到了解答,所以我不再深入讨论。至于您的第二个问题,Apple对mcontext和ucontext有自己的定义,特别是mcontext 64和ucontex 64。此外,您正在针对ARM 64而不是x86_64进行编译,因此这些寄存器将不再存在于您编译的二进制文件中。
进入你的构建设置-〉架构移除标准架构并用x86_64替换它,你的处理程序应该能够访问寄存器。