X-Git-Url: http://git.lttng.org/?a=blobdiff_plain;f=libust%2Ftracectl.c;h=5e59ca7bc0e8f5cf3ffee07cd6b25e06b3a98a3b;hb=616ed36a65d067de413ac5aca14d165cd5044b96;hp=f9312b4340238e79e3e2dd6abf51d82bd962cca1;hpb=55c5b393e9b197033ed1a6a8cc8f179412c61bf6;p=lttng-ust.git diff --git a/libust/tracectl.c b/libust/tracectl.c index f9312b43..5e59ca7b 100644 --- a/libust/tracectl.c +++ b/libust/tracectl.c @@ -30,6 +30,7 @@ #include #include +#include #include "tracer.h" #include "usterr.h" #include "ustcomm.h" @@ -1122,9 +1123,13 @@ void ust_potential_exec(void) * the new process, anytime a process whose memory is not shared with * the parent is created. If this function is not called, the events * of the new process will not be collected. + * + * Signals should be disabled before the fork and reenabled only after + * this call in order to guarantee tracing is not started before ust_fork() + * sanitizes the new process. */ -void ust_fork(void) +static void ust_fork(void) { struct blocked_consumer *bc; struct blocked_consumer *deletable_bc = NULL; @@ -1160,3 +1165,55 @@ void ust_fork(void) inform_consumer_daemon("auto"); } +void ust_before_fork(ust_fork_info_t *fork_info) +{ + /* Disable signals. This is to avoid that the child + * intervenes before it is properly setup for tracing. It is + * safer to disable all signals, because then we know we are not + * breaking anything by restoring the original mask. + */ + sigset_t all_sigs; + int result; + + /* FIXME: + - only do this if tracing is active + */ + + /* Disable signals */ + sigfillset(&all_sigs); + result = sigprocmask(SIG_BLOCK, &all_sigs, &fork_info->orig_sigs); + if(result == -1) { + PERROR("sigprocmask"); + return; + } +} + +/* Don't call this function directly in a traced program */ +static void ust_after_fork_common(ust_fork_info_t *fork_info) +{ + int result; + sigset_t orig_sigs; + + /* Restore signals */ + result = sigprocmask(SIG_SETMASK, &fork_info->orig_sigs, NULL); + if(result == -1) { + PERROR("sigprocmask"); + return; + } +} + +void ust_after_fork_parent(ust_fork_info_t *fork_info) +{ + /* Reenable signals */ + ust_after_fork_common(fork_info); +} + +void ust_after_fork_child(ust_fork_info_t *fork_info) +{ + /* First sanitize the child */ + ust_fork(); + + /* Then reenable interrupts */ + ust_after_fork_common(fork_info); +} +