Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 317986 Details for
Bug 464520
[utrace] PTRACE_O_TRACEVFORK no longer gives parent notification
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
test-vfork.c source file
test-vfork.c (text/plain), 4.84 KB, created by
Tom Horsley
on 2008-09-29 14:32:08 UTC
(
hide
)
Description:
test-vfork.c source file
Filename:
MIME Type:
Creator:
Tom Horsley
Created:
2008-09-29 14:32:08 UTC
Size:
4.84 KB
patch
obsolete
>#include <stdio.h> >#include <sys/ptrace.h> >#include <sys/types.h> >#include <signal.h> >#include <unistd.h> >#include <stdlib.h> >#include <sys/wait.h> > >/* >// On 2.6.26 kernels, vfork() no longer provides a parent stopped >// notification when the process that vforks is run under ptrace with all >// the PTRACE_O_* flags set to follow forks. >*/ > >char * >signal_name(int signum) { > switch (signum) { >#ifdef SIGHUP > case SIGHUP: return "SIGHUP"; >#endif >#ifdef SIGINT > case SIGINT: return "SIGINT"; >#endif >#ifdef SIGQUIT > case SIGQUIT: return "SIGQUIT"; >#endif >#ifdef SIGILL > case SIGILL: return "SIGILL"; >#endif >#ifdef SIGTRAP > case SIGTRAP: return "SIGTRAP"; >#endif >#ifdef SIGABRT > case SIGABRT: return "SIGABRT"; >#endif >#ifdef SIGBUS > case SIGBUS: return "SIGBUS"; >#endif >#ifdef SIGFPE > case SIGFPE: return "SIGFPE"; >#endif >#ifdef SIGKILL > case SIGKILL: return "SIGKILL"; >#endif >#ifdef SIGUSR1 > case SIGUSR1: return "SIGUSR1"; >#endif >#ifdef SIGSEGV > case SIGSEGV: return "SIGSEGV"; >#endif >#ifdef SIGUSR2 > case SIGUSR2: return "SIGUSR2"; >#endif >#ifdef SIGPIPE > case SIGPIPE: return "SIGPIPE"; >#endif >#ifdef SIGALRM > case SIGALRM: return "SIGALRM"; >#endif >#ifdef SIGTERM > case SIGTERM: return "SIGTERM"; >#endif >#ifdef SIGSTKFLT > case SIGSTKFLT: return "SIGSTKFLT"; >#endif >#ifdef SIGCHLD > case SIGCHLD: return "SIGCHLD"; >#endif >#ifdef SIGCONT > case SIGCONT: return "SIGCONT"; >#endif >#ifdef SIGSTOP > case SIGSTOP: return "SIGSTOP"; >#endif >#ifdef SIGTSTP > case SIGTSTP: return "SIGTSTP"; >#endif >#ifdef SIGTTIN > case SIGTTIN: return "SIGTTIN"; >#endif >#ifdef SIGTTOU > case SIGTTOU: return "SIGTTOU"; >#endif >#ifdef SIGURG > case SIGURG: return "SIGURG"; >#endif >#ifdef SIGXCPU > case SIGXCPU: return "SIGXCPU"; >#endif >#ifdef SIGXFSZ > case SIGXFSZ: return "SIGXFSZ"; >#endif >#ifdef SIGVTALRM > case SIGVTALRM: return "SIGVTALRM"; >#endif >#ifdef SIGPROF > case SIGPROF: return "SIGPROF"; >#endif >#ifdef SIGWINCH > case SIGWINCH: return "SIGWINCH"; >#endif >#ifdef SIGIO > case SIGIO: return "SIGIO"; >#endif >#ifdef SIGLOST > case SIGLOST: return "SIGLOST"; >#endif >#ifdef SIGPWR > case SIGPWR: return "SIGPWR"; >#endif >#ifdef SIGSYS > case SIGSYS: return "SIGSYS"; >#endif > default: > { > static char sval[512]; > sprintf(sval, "signal %d", signum); > return sval; > } > } >} > >char * >status_string(int kidstat) { > static char rval[512]; > if (WIFEXITED(kidstat)) { > if (WEXITSTATUS(kidstat) == 0) { > sprintf(rval, "exited normally"); > } else { > sprintf(rval, "exited with status %d", WEXITSTATUS(kidstat)); > } > } else if (WIFSIGNALED(kidstat)) { > sprintf(rval, "terminated with %s", signal_name(WTERMSIG(kidstat))); > } else if (WIFSTOPPED(kidstat)) { > sprintf(rval, "stopped with %s", signal_name(WSTOPSIG(kidstat))); > } else { > sprintf(rval, "unrecognized status %#x", kidstat); > } > return rval; >} > >static void >test_vfork() { > pid_t gkid; > if (ptrace(PTRACE_TRACEME, 0, 0, 0) == -1) { > perror("ptrace(PTRACE_TRACEME)"); > exit(2); > } > > /* First, let parent know I'm here by sending myself a signal */ > > if (kill(getpid(), SIGUSR1) == -1) { > perror("kill"); > exit(2); > } > > /* Now vfork() and see what parent thinks of that... */ > > gkid = vfork(); > if (gkid == (pid_t)-1) { > perror("vfork"); > } > exit(0); >} > >int >main(int argc, char ** argv) { > pid_t child; > > child = fork(); > if (child == (pid_t)-1) { > perror("fork"); > exit(2); > } else if (child == 0) { > test_vfork(); > } else { > /* I am the parent, I'll be debugging the child which will > * call vfork(). The first thing I expect to see from the > * child is a SIGUSR1 it sends to itself. > */ > int waitstat; > printf("Child process is %d\n", (int)child); > if (waitpid(child, &waitstat, WUNTRACED|__WALL) != child) { > perror("waitpid"); > exit(2); > } > /* Set all the trace flags so we'll follow fork and wot-not */ > if (ptrace(PTRACE_SETOPTIONS, child, 0, > PTRACE_O_TRACEFORK| > PTRACE_O_TRACEVFORK| > PTRACE_O_TRACECLONE| > PTRACE_O_TRACEEXEC| > PTRACE_O_TRACEEXIT) == -1) { > perror("ptrace(PTRACE_SETOPTIONS)"); > exit(2); > } > > /* Now I continue the child, but don't pass the SIGUSR1 > * so it will just execute normally without getting the signal. > */ > if (ptrace(PTRACE_CONT, child, 0, 0) == -1) { > perror("ptrace"); > exit(2); > } > /* Now loop forever, printing info about any status I get. */ > for ( ; ; ) { > pid_t kid = waitpid((pid_t)-1, &waitstat, WUNTRACED|__WALL); > if (kid == (pid_t)-1) { > perror("waitpid"); > exit(2); > } > printf("Status for PID %d: %s\n", (int)kid, status_string(waitstat)); > } > } >}
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 464520
: 317986 |
319218
|
319237
|
321611