FreeBSD Bugzilla – Attachment 223168 Details for
Bug 254201
ptrace(): rfork(RFSPAWN) / posix_spawn() reports fork instead of vfork (+ vfork_done)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
reproducer
simple-fbsd-spawn.c (text/plain), 2.82 KB, created by
Michał Górny
on 2021-03-10 18:54:29 UTC
(
hide
)
Description:
reproducer
Filename:
MIME Type:
Creator:
Michał Górny
Created:
2021-03-10 18:54:29 UTC
Size:
2.82 KB
patch
obsolete
>#include <sys/types.h> >#include <sys/ptrace.h> >#include <sys/wait.h> > >#include <assert.h> >#include <signal.h> >#include <spawn.h> >#include <stdio.h> >#include <stdlib.h> >#include <string.h> >#include <unistd.h> > >int main() { > int ret; > pid_t pid = fork(); > assert(pid != -1); > > if (pid == 0) { > /* child -- debugged program */ > /* request tracing */ > ret = ptrace(PT_TRACE_ME, 0, NULL, 0); > assert(ret != -1); > ret = raise(SIGSTOP); > assert(ret != -1); > > char* new_argv[] = {"true", NULL}; > posix_spawnp(NULL, "true", NULL, NULL, new_argv, NULL); > > _exit(0); > } > > /* parent -- the debugger */ > pid_t waited; > > /* 1. SIGSTOP for the process */ > waited = waitpid(pid, &ret, 0); > assert(waited == pid); > assert(WIFSTOPPED(ret)); > assert(WSTOPSIG(ret) == SIGSTOP); > > /* set the event mask */ > int event_mask = PTRACE_FORK | PTRACE_VFORK | PTRACE_EXEC; > ret = ptrace(PT_SET_EVENT_MASK, waited, > (void*)&event_mask, > sizeof(event_mask)); > assert(ret == 0); > > ret = ptrace(PT_CONTINUE, waited, (void*)1, 0); > assert(ret == 0); > > /* 2. SIGTRAP for fork */ > waited = waitpid(pid, &ret, 0); > assert(waited == pid); > assert(WIFSTOPPED(ret)); > assert(WSTOPSIG(ret) == SIGTRAP); > > struct ptrace_lwpinfo info; > ret = ptrace(PT_LWPINFO, waited, (void*)&info, sizeof(info)); > assert(ret == 0); > assert(info.pl_flags & PL_FLAG_FORKED); > > ret = ptrace(PT_CONTINUE, waited, (void*)1, 0); > assert(ret == 0); > > /* 3. SIGCHLD for the child */ > waited = waitpid(info.pl_child_pid, &ret, 0); > assert(waited != pid); > assert(WIFSTOPPED(ret)); > assert(WSTOPSIG(ret) == SIGSTOP); > > ret = ptrace(PT_CONTINUE, waited, (void*)1, 0); > assert(ret == 0); > > /* 4. SIGCHLD for the exec in child */ > waited = waitpid(info.pl_child_pid, &ret, 0); > assert(waited != pid); > assert(WIFSTOPPED(ret)); > assert(WSTOPSIG(ret) == SIGTRAP); > > ret = ptrace(PT_LWPINFO, waited, (void*)&info, sizeof(info)); > assert(ret == 0); > assert(info.pl_flags & PL_FLAG_EXEC); > > ret = ptrace(PT_CONTINUE, waited, (void*)1, 0); > assert(ret == 0); > > /* 5. SIGTRAP for vfork_done */ > waited = waitpid(pid, &ret, 0); > assert(waited == pid); > assert(WIFSTOPPED(ret)); > assert(WSTOPSIG(ret) == SIGTRAP); > > ret = ptrace(PT_LWPINFO, waited, (void*)&info, sizeof(info)); > assert(ret == 0); > assert(info.pl_flags & PL_FLAG_VFORK_DONE); > > ret = ptrace(PT_CONTINUE, waited, (void*)1, 0); > assert(ret == 0); > > /* 6. exit for both */ > waited = waitpid(pid, &ret, 0); > assert(waited == pid); > assert(WIFEXITED(ret)); > assert(WEXITSTATUS(ret) == 0); > > waited = waitpid(-1, &ret, 0); > assert(waited != pid); > assert(WIFEXITED(ret)); > assert(WEXITSTATUS(ret) == 0); > > return 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 254201
: 223168