Skip to content

Commit

Permalink
Handle PTRACE_EVENT_* events for child processes/threads.
Browse files Browse the repository at this point in the history
While we so far support clone(2), fork(2), vfork(2), there
are other variants we don't. In my testing I found a case
where gcc utilized clone3(2), resulting in build-recorder
not recording the process creation step.

This commit follows a second approach utilizing the signals
ptrace(2) delivers to inform the tracer of a new process
or thread.

Signed-off-by: Fotios Valasiadis <[email protected]>
  • Loading branch information
fvalasiad committed Aug 28, 2024
1 parent e8072d4 commit 987d408
Showing 1 changed file with 21 additions and 31 deletions.
52 changes: 21 additions & 31 deletions src/tracer.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,19 +377,6 @@ handle_rename_exit(pid_t pid, PROCESS_INFO *pi, int newdirfd, char *newpath)
record_rename(pi->outname, from->outname, to->outname);
}

static void
handle_create_process(PROCESS_INFO *pi, pid_t child)
{
PROCESS_INFO *child_pi = find_pinfo(child);

if (!child_pi) {
child_pi = next_pinfo(child);
pinfo_new(child_pi, 1);
}

record_process_create(pi->outname, child_pi->outname);
}

static void
handle_syscall_entry(pid_t pid, PROCESS_INFO *pi,
const struct ptrace_syscall_info *entry)
Expand Down Expand Up @@ -561,24 +548,6 @@ handle_syscall_exit(pid_t pid, PROCESS_INFO *pi,

handle_rename_exit(pid, pi, newdirfd, newpath);
break;
#endif
#ifdef HAVE_SYS_FORK
case SYS_fork:
// pid_t fork(void);
handle_create_process(pi, exit->exit.rval);
break;
#endif
#ifdef HAVE_SYS_VFORK
case SYS_vfork:
// pid_t vfork(void);
handle_create_process(pi, exit->exit.rval);
break;
#endif
#ifdef HAVE_SYS_CLONE
case SYS_clone:
// int clone(...);
handle_create_process(pi, exit->exit.rval);
break;
#endif
}
}
Expand Down Expand Up @@ -665,6 +634,27 @@ tracer_main(pid_t pid, PROCESS_INFO *pi, char *path, char **envp)
case SIGTRAP:
// Also ignore SIGTRAPs since they are
// generated by ptrace(2)
switch (status >> 8) {
case SIGTRAP | (PTRACE_EVENT_VFORK << 8):
case SIGTRAP | (PTRACE_EVENT_FORK << 8):
case SIGTRAP | (PTRACE_EVENT_CLONE << 8):
pid_t child;

if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &child) <
0) {
perror("tracer.c:tracer_main():ptrace(PTRACE_GETEVENTMSG)");
exit(EXIT_FAILURE);
}

PROCESS_INFO *child_pi = find_pinfo(child);

if (!child_pi) {
child_pi = next_pinfo(child);
pinfo_new(child_pi, 1);
}
record_process_create(pi->outname,
child_pi->outname);
}
break;
default:
restart_sig = WSTOPSIG(status);
Expand Down

0 comments on commit 987d408

Please sign in to comment.