projects
/
lttng-ust.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fix: liblttng-ust-fork deadlock
[lttng-ust.git]
/
liblttng-ust
/
lttng-ust-comm.c
diff --git
a/liblttng-ust/lttng-ust-comm.c
b/liblttng-ust/lttng-ust-comm.c
index 12385dfca95762d32839b4e5917a92f8b82b4c58..8c864f8ce595621434cfac4a08dec1aa705d5671 100644
(file)
--- a/
liblttng-ust/lttng-ust-comm.c
+++ b/
liblttng-ust/lttng-ust-comm.c
@@
-78,6
+78,12
@@
static sem_t constructor_wait;
*/
static int sem_count = { 2 };
*/
static int sem_count = { 2 };
+/*
+ * Counting nesting within lttng-ust. Used to ensure that calling fork()
+ * from liblttng-ust does not execute the pre/post fork handlers.
+ */
+static int __thread lttng_ust_nest_count;
+
/*
* Info about socket and associated listener thread.
*/
/*
* Info about socket and associated listener thread.
*/
@@
-469,7
+475,9
@@
int get_wait_shm(struct sock_info *sock_info, size_t mmap_size)
* If the open failed because the file did not exist, try
* creating it ourself.
*/
* If the open failed because the file did not exist, try
* creating it ourself.
*/
+ lttng_ust_nest_count++;
pid = fork();
pid = fork();
+ lttng_ust_nest_count--;
if (pid > 0) {
int status;
if (pid > 0) {
int status;
@@
-883,15
+891,20
@@
void __attribute__((constructor)) lttng_ust_init(void)
sigfillset(&sig_all_blocked);
ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_parent_mask);
if (ret) {
sigfillset(&sig_all_blocked);
ret = pthread_sigmask(SIG_SETMASK, &sig_all_blocked, &orig_parent_mask);
if (ret) {
-
PERRO
R("pthread_sigmask: %s", strerror(ret));
+
ER
R("pthread_sigmask: %s", strerror(ret));
}
ret = pthread_create(&global_apps.ust_listener, NULL,
ust_listener_thread, &global_apps);
}
ret = pthread_create(&global_apps.ust_listener, NULL,
ust_listener_thread, &global_apps);
-
+ if (ret) {
+ ERR("pthread_create global: %s", strerror(ret));
+ }
if (local_apps.allowed) {
ret = pthread_create(&local_apps.ust_listener, NULL,
ust_listener_thread, &local_apps);
if (local_apps.allowed) {
ret = pthread_create(&local_apps.ust_listener, NULL,
ust_listener_thread, &local_apps);
+ if (ret) {
+ ERR("pthread_create local: %s", strerror(ret));
+ }
} else {
handle_register_done(&local_apps);
}
} else {
handle_register_done(&local_apps);
}
@@
-899,7
+912,7
@@
void __attribute__((constructor)) lttng_ust_init(void)
/* Restore original signal mask in parent */
ret = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL);
if (ret) {
/* Restore original signal mask in parent */
ret = pthread_sigmask(SIG_SETMASK, &orig_parent_mask, NULL);
if (ret) {
-
PERRO
R("pthread_sigmask: %s", strerror(ret));
+
ER
R("pthread_sigmask: %s", strerror(ret));
}
switch (timeout_mode) {
}
switch (timeout_mode) {
@@
-975,12
+988,14
@@
void __attribute__((destructor)) lttng_ust_exit(void)
/* cancel threads */
ret = pthread_cancel(global_apps.ust_listener);
if (ret) {
/* cancel threads */
ret = pthread_cancel(global_apps.ust_listener);
if (ret) {
- ERR("Error cancelling global ust listener thread");
+ ERR("Error cancelling global ust listener thread: %s",
+ strerror(ret));
}
if (local_apps.allowed) {
ret = pthread_cancel(local_apps.ust_listener);
if (ret) {
}
if (local_apps.allowed) {
ret = pthread_cancel(local_apps.ust_listener);
if (ret) {
- ERR("Error cancelling local ust listener thread");
+ ERR("Error cancelling local ust listener thread: %s",
+ strerror(ret));
}
}
/*
}
}
/*
@@
-1012,6
+1027,8
@@
void ust_before_fork(sigset_t *save_sigset)
sigset_t all_sigs;
int ret;
sigset_t all_sigs;
int ret;
+ if (lttng_ust_nest_count)
+ return;
/* Disable signals */
sigfillset(&all_sigs);
ret = sigprocmask(SIG_BLOCK, &all_sigs, save_sigset);
/* Disable signals */
sigfillset(&all_sigs);
ret = sigprocmask(SIG_BLOCK, &all_sigs, save_sigset);
@@
-1037,6
+1054,8
@@
static void ust_after_fork_common(sigset_t *restore_sigset)
void ust_after_fork_parent(sigset_t *restore_sigset)
{
void ust_after_fork_parent(sigset_t *restore_sigset)
{
+ if (lttng_ust_nest_count)
+ return;
DBG("process %d", getpid());
rcu_bp_after_fork_parent();
/* Release mutexes and reenable signals */
DBG("process %d", getpid());
rcu_bp_after_fork_parent();
/* Release mutexes and reenable signals */
@@
-1054,6
+1073,8
@@
void ust_after_fork_parent(sigset_t *restore_sigset)
*/
void ust_after_fork_child(sigset_t *restore_sigset)
{
*/
void ust_after_fork_child(sigset_t *restore_sigset)
{
+ if (lttng_ust_nest_count)
+ return;
DBG("process %d", getpid());
/* Release urcu mutexes */
rcu_bp_after_fork_child();
DBG("process %d", getpid());
/* Release urcu mutexes */
rcu_bp_after_fork_child();
This page took
0.027482 seconds
and
4
git commands to generate.