我正试图从我的程序中捕获SIGSEGV
。我遇到了一个问题,我的signal_handler没有捕获到信号。
void handler(int sig){
printf("catch SIGSEGV");
exit(EXIT_FAILURE);
}
void foo(){
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
if(sigaction(SIGSEGV, &sa, NULL) == -1){
handle_error("sigaction");
}
/* if SIGSEGV happen here, I can catch it */
bar();
}
void bar() {
/* if SIGSEGV happen here, I cannot catch it */
}
这是否意味着我必须在栏内安装另一个信号处理程序?
但是如果我有一堆想要捕获相同信号的函数怎么办呢。我必须多次安装信号处理程序?
更新:
我试图直接在函数中安装处理程序但仍然无法捕获它。所以我认为这可能是其他问题。但那很奇怪。我使用gdb来运行并获取
Program received signal SIGSEGV, Segmentation fault.
0x080499b1 in is_printable_string (
str=0xb80fe768 <Address 0xb80fe768 out of bounds>)
at trace/trace.c:259
259 while(str[index]!='\0'){
这是我的is_printable_String
int is_printable_string(char *str){
struct sigaction sa;
sa.sa_flags = SA_SIGINFO;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = handler;
if(sigaction(SIGSEGV, &sa, NULL) == -1){
handle_error("sigaction");
}
int index;
index=0;
while(str[index]!='\0'){
if(!isprint(str[index])){
return -1;
}
index++;
}
/* continue... */
这似乎我得到了一个SEG故障,但我无法抓住它
我故意传递了那个指针,所以str
参数没有错。
答案 0 :(得分:1)
来自sigaction ...
的手册页SA_SIGINFO(自Linux 2.2起)信号处理程序采用三个参数, 不是一个。在这种情况下,应该设置sa_sigaction而不是 sa_handler。该标志仅在建立信号时有意义 处理程序。
因此,您的问题应该是
行sa.sa_flags = SA_SIGINFO;
将其更改为
sa.sa_flags = 0;
看看它是怎么回事。
答案 1 :(得分:1)
确实,因为ajcaruana指出你的处理程序与SA_SIGINFO
不匹配。但是,如果您正在捕捉SIGSEGV
,您可能需要SA_SIGINFO,以查看有问题的地址和内容。在这种情况下,您的信号处理程序需要如下所示:
static void
handler(int sig, siginfo_t *si, void *ucontext)
{
/* ... */
}
特别是,您可能对si_addr
:
对于SIGBUS和SIGSEGV信号,该字段包含地址 导致无效的内存引用。