From b31398bb2b3fa91a53dea3b36fd693da4b50e0d3 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Fri, 17 May 2013 14:08:14 -0400 Subject: [PATCH] Fix: increment UST channel refcount at stream creation Having the channel refcount incremented only when the stream is sent to a thread could triggered a segfault with a race between a channel destroyed by the channel thread and the stream pointers being inflight in the thread pipe. Once read from the pipe, the streams are added to the data thread poll set and immediately destroyed since the channel has hung up previously but the flush buffer segfaulted on the channel that was already deleted by the channel thread with a refcount set to 0. This is fixed by incrementing the channel refcount once the stream is created and the channel reference is set to it. This is done *before* the channel object is visible in the channel thread. Now the channel thread detects the hang up but will not destroy the channel because of the refcount > 0. The channel cleanup will be done by the last stream hanging up. Fixes #530 Acked-by: Mathieu Desnoyers Signed-off-by: David Goulet --- src/common/consumer.c | 3 --- src/common/ust-consumer/ust-consumer.c | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/common/consumer.c b/src/common/consumer.c index 2dd463c14..e26388f8e 100644 --- a/src/common/consumer.c +++ b/src/common/consumer.c @@ -660,9 +660,6 @@ static int add_stream(struct lttng_consumer_stream *stream, uatomic_inc(&relayd->refcount); } - /* Update channel refcount once added without error(s). */ - uatomic_inc(&stream->chan->refcount); - /* * When nb_init_stream_left reaches 0, we don't need to trigger any action * in terms of destroying the associated channel, because the action that diff --git a/src/common/ust-consumer/ust-consumer.c b/src/common/ust-consumer/ust-consumer.c index 031a7cb26..01fca9b7f 100644 --- a/src/common/ust-consumer/ust-consumer.c +++ b/src/common/ust-consumer/ust-consumer.c @@ -278,6 +278,12 @@ static int create_ust_streams(struct lttng_consumer_channel *channel, */ stream->wait_fd = wait_fd; + /* + * Increment channel refcount since the channel reference has now been + * assigned in the allocation process above. + */ + uatomic_inc(&stream->chan->refcount); + /* * Order is important this is why a list is used. On error, the caller * should clean this list. -- 2.34.1