0

For test1.c, I get:

5
133
1
0

It means that the child process firstly get SIGTRAP (5), cause by execl. The last three lines indicate that the child process dies due to the SIGSTRAP signal from the parent.

// test1.c
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <stdio.h>
#include <pthread.h>

int main() {
  pid_t child;
  int status = 0;
  child = fork();
  if(child == 0) {
    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    execl("/bin/ls", "ls", NULL);
  } else {
    wait(&status);
    printf("%d\n", status >> 8);
    ptrace(PTRACE_CONT, child, NULL, SIGTRAP);

    wait(&status);
    printf("%d\n", status);
    printf("%d\n", WIFSIGNALED(status));
    printf("%d\n", WIFEXITED(status));
  }
  return 0;
}

For test2.c, I get:

19
1029
0
0
1

19 is SIGSTOP, and 1029 is (SIGTRAP | (PTRACE_EVENT_EXEC<<8)), but the last threes lines are beyond me. Why does the child process exit normally? What happend to the SIGTRAP signal from the parent?

// test2.c
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/reg.h>
#include <stdio.h>
#include <pthread.h>
int main() {
  pid_t child;
  int status = 0;
  child = fork();
  if(child == 0) {
    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    raise(SIGSTOP);
    execl("/bin/ls", "ls", NULL);
  } else {
    wait(&status);
    ptrace(PTRACE_SETOPTIONS, child, 0, PTRACE_O_TRACEEXEC);
    printf("%d\n", status >> 8);
    ptrace(PTRACE_CONT, child, NULL, 0);

    wait(&status);
    printf("%d\n", status >> 8);
    ptrace(PTRACE_CONT, child, NULL, SIGTRAP);

    wait(&status);
    printf("%d\n", status);
    printf("%d\n", WIFSIGNALED(status));
    printf("%d\n", WIFEXITED(status));
  }
  return 0;
}
melpomene
  • 84,125
  • 8
  • 85
  • 148
Albert Netymk
  • 1,102
  • 8
  • 24

1 Answers1

1

When dispatching a SIGNAL by the tracer with

ptrace(PTRACE_CONT, child, NULL, SIGXXXX);

The tracer is not notified for that signal - which makes sense. Otherwise, how else would you dispach a signal to a the tracee? You will always catch it.

PTRACE_CONT Restart the stopped tracee process. If data is nonzero, it is interpreted as the number of a signal to be delivered to the tracee; otherwise, no signal is delivered. Thus, for example, the tracer can control whether a signal sent to the tracee is delivered or not.

If you want to stop the child from the parent you should use

kill(child_pid, SIGTRAP)

So, I guess that when you send the SIGTRAP in the first example - you simply send an unhandled signal to the process which will probably kill him.

I the other hand - PTRACE_TRACEME doesn't cause the the child to stop, so, it might as well already finished its exection when the SIGTRAP is dispatched.

Eytan Naim
  • 159
  • 14