[英]WIFSIGNALED returns false even if I send a signal with the kill command on Linux(Mint 18.3)
[英]WIFSIGNALED not catching SEGFAULT signal
我相當確定 WIFEXITED 和 WIFSIGNALED 是什么以及它們是如何工作的。 我不知道為什么它不工作,因為程序發生了段錯誤,我可以很好地看到(調試)第三次迭代的信號是 SEGFAULT。 感謝您提供任何信息。
segfault_prog
#include <stdlib.h>
#include <stdio.h>
int main() {
int *i = 0x478734;
printf("%d", *i);
}
int main(void) {
int status;
int ret = fork();
if (ret == 0) {
ptrace(PTRACE_TRACEME, ret, NULL, NULL);
raise(SIGSTOP);
execve(argv[1], &argv[1], NULL);
return 1;
}
else {
while (1) {
pid_t val = waitpid(ret, &status, 0);
ptrace(PTRACE_SETOPTIONS, ret, 0,PTRACE_O_EXITKILL | PTRACE_O_TRACEEXEC);
if (WIFEXITED(status) && val == ret){
printf("exited normally");
return WEXITSTATUS (status);
}
else if (WIFSIGNALED(status)){
//if I change for WEXITSTATUS(status) == SIGSEGV. then it works. First while iteration wIFEXITVAL(SIGSTOP/19), 2nd (SIGTRAP/5), 3rd (SIGSEGV 11);
printf("signal error");
return WEXITSTATUS (status);
}
ptrace(PTRACE_CONT, val, 0, 0);
}
}
return (0);
}
幾個問題...
當tracee/child 停止時(即WIFSTOPPED),信號(即WSTOPSIG)必須向下發送到tracee。 這是PTRACE_CONT
的最后一個參數
僅在第一個waitpid
之后才需要執行PTRACE_SETOPTIONS
waitpid
的第一個參數應該是-1
來捕獲所有的孩子
通過不通過PTRACE_CONT
[AFAICT] 向下發送信號,信號被延遲[直到跟蹤器選擇向下發送信號]。 因此,被跟蹤者/孩子生成了信號,但它從未發送給被跟蹤者/孩子。
另外,正如我所提到的,您可能想看看我最近的回答: ptrace options not working in parent process
這是重構的代碼。 它帶有錯誤和修復注釋:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
int
main(int argc,char **argv)
{
int status;
int ret = fork();
if (ret == 0) {
ptrace(PTRACE_TRACEME, ret, NULL, NULL);
// NOTE/BUG: not needed
#if 0
raise(SIGSTOP);
#endif
execve(argv[1], &argv[1], NULL);
#if 0
return 1;
#else
exit(1);
#endif
}
#if TEST
int iter = 20;
#else
int iter = 0x7FFFFFFF;
#endif
int first = 1;
for (; iter > 0; --iter) {
// NOTE/BUG: we should catch all children (tracee might do fork but not wait
// and orphan/zombie its child (our grandchild) and we'd want to see that)
#if 0
pid_t val = waitpid(ret, &status, 0);
#else
pid_t val = waitpid(-1, &status, 0);
#endif
#if 1
if (first) {
ptrace(PTRACE_SETOPTIONS, ret, 0,
PTRACE_O_EXITKILL | PTRACE_O_TRACEEXEC);
first = 0;
}
#endif
printf("pt: status=%8.8X\n",status);
int signo = 0;
if (WIFEXITED(status)) {
printf("pt: WIFEXITED %d\n",WEXITSTATUS(status));
}
if (WIFSTOPPED(status)) {
signo = WSTOPSIG(status);
printf("pt: WIFSTOPPED %d\n",signo);
if (signo == SIGTRAP)
signo = 0;
}
if (WIFSIGNALED(status)) {
printf("pt: WIFSIGNALED %d\n",WTERMSIG(status));
}
if (WIFEXITED(status) && val == ret) {
printf("exited normally");
return WEXITSTATUS(status);
}
else if (WIFSIGNALED(status)) {
// if I change for WEXITSTATUS(status) == SIGSEGV. then it works.
// First while iteration wIFEXITVAL(SIGSTOP/19), 2nd (SIGTRAP/5),
// 3rd (SIGSEGV 11);
#if 0
printf("signal error");
#else
printf("signal error -- %d\n",WTERMSIG(status));
#endif
return WEXITSTATUS(status);
}
// NOTE/BUG: must send signo from WIFSTOPPED/WSTOPSIG to tracee
#if SHOWBUG
ptrace(PTRACE_CONT, val, 0, 0);
#else
ptrace(PTRACE_CONT, val, 0, signo);
#endif
}
if (iter <= 0)
printf("pt: fault -- not seen\n");
return (0);
}
在上面的代碼中,我使用cpp
條件來表示舊代碼和新代碼:
#if 0
// old code
#else
// new code
#endif
#if 1
// new code
#endif
這是原始行為(使用-DTEST -DSHOWBUG
編譯):
pt: status=0000057F
pt: WIFSTOPPED 5
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: fault -- not seen
這是修復后的輸出:
pt: status=0000057F
pt: WIFSTOPPED 5
pt: status=00000B7F
pt: WIFSTOPPED 11
pt: status=0000008B
pt: WIFSIGNALED 11
signal error -- 11
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.