Skip to content

Commit a18f00b

Browse files
committed
Handle PTRACE_EVENT_* events for child processes/threads.
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]>
1 parent 1054cd4 commit a18f00b

File tree

1 file changed

+21
-31
lines changed

1 file changed

+21
-31
lines changed

src/tracer.c

+21-31
Original file line numberDiff line numberDiff line change
@@ -377,19 +377,6 @@ handle_rename_exit(pid_t pid, PROCESS_INFO *pi, int newdirfd, char *newpath)
377377
record_rename(pi->outname, from->outname, to->outname);
378378
}
379379

380-
static void
381-
handle_create_process(PROCESS_INFO *pi, pid_t child)
382-
{
383-
PROCESS_INFO *child_pi = find_pinfo(child);
384-
385-
if (!child_pi) {
386-
child_pi = next_pinfo(child);
387-
pinfo_new(child_pi, 1);
388-
}
389-
390-
record_process_create(pi->outname, child_pi->outname);
391-
}
392-
393380
static void
394381
handle_syscall_entry(pid_t pid, PROCESS_INFO *pi)
395382
{
@@ -556,24 +543,6 @@ handle_syscall_exit(pid_t pid, PROCESS_INFO *pi, int64_t rval)
556543

557544
handle_rename_exit(pid, pi, newdirfd, newpath);
558545
break;
559-
#endif
560-
#ifdef HAVE_SYS_FORK
561-
case SYS_fork:
562-
// pid_t fork(void);
563-
handle_create_process(pi, rval);
564-
break;
565-
#endif
566-
#ifdef HAVE_SYS_VFORK
567-
case SYS_vfork:
568-
// pid_t vfork(void);
569-
handle_create_process(pi, rval);
570-
break;
571-
#endif
572-
#ifdef HAVE_SYS_CLONE
573-
case SYS_clone:
574-
// int clone(...);
575-
handle_create_process(pi, rval);
576-
break;
577546
#endif
578547
}
579548
}
@@ -662,6 +631,27 @@ tracer_main(pid_t pid, PROCESS_INFO *pi, char *path, char **envp)
662631
case SIGTRAP:
663632
// Also ignore SIGTRAPs since they are
664633
// generated by ptrace(2)
634+
switch (status >> 8) {
635+
case SIGTRAP | (PTRACE_EVENT_VFORK << 8):
636+
case SIGTRAP | (PTRACE_EVENT_FORK << 8):
637+
case SIGTRAP | (PTRACE_EVENT_CLONE << 8):
638+
pid_t child;
639+
640+
if (ptrace(PTRACE_GETEVENTMSG, pid, NULL, &child) <
641+
0) {
642+
perror("tracer.c:tracer_main():ptrace(PTRACE_GETEVENTMSG)");
643+
exit(EXIT_FAILURE);
644+
}
645+
646+
PROCESS_INFO *child_pi = find_pinfo(child);
647+
648+
if (!child_pi) {
649+
child_pi = next_pinfo(child);
650+
pinfo_new(child_pi, 1);
651+
}
652+
record_process_create(pi->outname,
653+
child_pi->outname);
654+
}
665655
break;
666656
default:
667657
restart_sig = WSTOPSIG(status);

0 commit comments

Comments
 (0)