我正在尝试监视子进程的段错误错误,但这不起作用。
我总是收到ABRT信号。
我看到gdb可以捕获段错误,所以我的代码出了什么问题?
pid_t child;
int wstatus, signum;
struct user_regs_struct regs;
child = fork();
if (child == 0)
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
char buf[10];
// make it always crash
strcpy (buf, "aaaaaaabbbbbbbbbbbaaaaaaaaaaaaaaaa");
printf ("Buf is %s\n", buf);
exit(0);
}
while(1)
{
wait(&wstatus);
if (WIFEXITED(wstatus) || WIFSIGNALED(wstatus))
break;
signum = WSTOPSIG(wstatus);
ptrace(PTRACE_GETREGS, child, NULL, ®s);
printf ("signal: %d, eip: 0x%08lx\n", signum, regs.eip);
ptrace(PTRACE_CONT, child, NULL, signum);
}
答案 0 :(得分:2)
我的代码出了什么问题
当孩子发出信号(WIFSIGNALED
)时,你的代码就会突破循环。既然你期望捕捉到一个信号(最有可能是SIGSEGV
),也许你不应该在孩子发出信号时突然出现这个问题?
我已经看了你的代码了。目前尚不清楚为什么你的孩子在崩溃。也许您正在使用-fstack-protector
或其他类似内容构建它?
这是一个完整的可编译测试用例(你应该已经提到你的问题中),这确实崩溃了(注意:从孩子那里删除了exit
):
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <wait.h>
#include <sys/ptrace.h>
#include <sys/user.h>
int main()
{
pid_t child;
int wstatus, signum;
struct user_regs_struct regs;
child = fork();
if (child == 0)
{
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
char buf[10];
// make it always crash
strcpy (buf, "aaaaaaabbbbbbbbbbbaaaaaaaaaaaaaaaa");
printf ("Buf is %s\n", buf);
}
while(1)
{
wait(&wstatus);
if (WIFEXITED(wstatus))
break;
signum = WSTOPSIG(wstatus);
ptrace(PTRACE_GETREGS, child, NULL, ®s);
printf ("signal: %d, eip: 0x%08lx\n", signum, regs.eip);
ptrace(PTRACE_CONT, child, NULL, signum);
}
return wstatus;
}
并获得无限循环
你通常 应该获得一个无限循环:你正在恢复孩子,它重新执行当前的指令,这应该再次触发完全相同的信号。
这不是我的系统上面的程序发生的事情,但我目前无法解释我在观察的内容:
$ ./a.out
Buf is aaaaaaabbbbbbbbbbbaaaaaaaaaaaaaaaa
signal: 159, eip: 0x08049ff4
signal: 159, eip: 0x08049ff4
...
signal: 159, eip: 0x08049ff4
*** stack smashing detected ***: ./a.out terminated
signal: 11, eip: 0xf759fb19
signal: 0, eip: 0xf759fb19
signal: 0, eip: 0xf759fb19
...