<分区>
有没有办法找出被某些信号中断的机器指令的地址?假设我们在 sigaction()
建立的处理程序中,并且可以访问传递的 siginfo_t
和 ucontext_t
。
据我所知,手册页对此只字不提。
<分区>
有没有办法找出被某些信号中断的机器指令的地址?假设我们在 sigaction()
建立的处理程序中,并且可以访问传递的 siginfo_t
和 ucontext_t
。
据我所知,手册页对此只字不提。
最佳答案
让我们看看下面的 linux 和 x86 架构示例
#include<stdio.h>
#define __USE_GNU
#include<signal.h>
#include<ucontext.h>
void myhandle(int mysignal, siginfo_t *si, void* arg)
{
ucontext_t *context = (ucontext_t *)arg;
printf("Address from where crash happen is %x \n",context->uc_mcontext.gregs[REG_RIP]);
context->uc_mcontext.gregs[REG_RIP] = context->uc_mcontext.gregs[REG_RIP] + 0x04 ;
}
int main(int argc, char *argv[])
{
struct sigaction action;
action.sa_sigaction = &myhandle;
action.sa_flags = SA_SIGINFO;
sigaction(11,&action,NULL);
printf("Before segfault\n");
int *a=NULL;
int b;
b =*a; // Here crash will hapen
printf("I am still alive\n");
return 0;
}
现在编译运行,看看反编译的指令集。
jeegar@jeegar:~/stackoverflow$ gcc -g test1.c -o test1.o
jeegar@jeegar:~/stackoverflow$ ./test1.o
Before segfault
Signal is 11
Address from where crash happen is 40065b
I am still alive
jeegar@jeegar:~/stackoverflow$ objdump -S test1.o
在对象转储中
printf("Before segfault\n");
400645: bf a8 07 40 00 mov $0x4007a8,%edi
40064a: e8 21 fe ff ff callq 400470 <puts@plt>
int *a=NULL;
40064f: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
400656: 00
int b;
b =*a; // Here crash will hapen
400657: 48 8b 45 f0 mov -0x10(%rbp),%rax
40065b: 8b 00 mov (%rax),%eax
40065d: 89 45 fc mov %eax,-0x4(%rbp)
printf("I am still alive\n");
400660: bf b8 07 40 00 mov $0x4007b8,%edi
400665: e8 06 fe ff ff callq 400470 <puts@plt>
在 40065b 地址处有哪个机器代码以及您的代码的哪一行完成了此操作。
这里我给了你和示例代码,在发生分段的地方和系统的段故障信号上将调用一个处理程序,并且我已经获取了最后执行的机器周期的地址并打印该地址。为了验证该地址,我还显示了该代码的对象转储和段错误行的机器指令匹配。
我想这就是你想要的。
关于c - Linux 信号处理。如何获取中断指令的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34989829/