From 0f664be0a2c54bf699f9772d8e40067ad4be9d5a Mon Sep 17 00:00:00 2001
From: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Date: Tue, 22 Jun 2021 22:17:03 -0400
Subject: [PATCH lttng-tools 1/2] Fix: UST communication can return -EAGAIN

Observed issue
==============

The following scenario lead to error on session configuration. The
problem manifest itself when an application is unresponsive. Note that
the default timeout for ust communication is 5 seconds.

  # Start an instrumented app
  ./app
  gdb lttng-sessiond
  # put a breakpoint in ust_consumer_send_stream_to_ust
  lttng create my_session
  lttng enable-event -u -a
  # The tracepoint should hit. Do not continue.
  kill -s SIGSTOP $(pgrep app)
  # Continue lttng-sessiond.

"lttng enable-event -u -a" will fail.

Note that for UST this is not an expected behaviour. Communication with
a single app should not invalidate the complete channel or at least
compromise its setup.

Note that a similar scenario for the following ustctl call sites also
lead to problems of similar nature:

  ustctl_create_event
  ustctl_enable_event
  ustctl_send_channel_to_ust
  ustctl_set_exclusion
  ustctl_set_filter

These callsites are also fixed by this patch.

Cause
=====

For an unresponsive application, EAGAIN is returned and is treated as an
"unknown" hard error by the caller of ust_consumer_send_stream_to_ust.

Solution
========

Handle EAGAIN coming from ustctl_* and treat it the same way a
dying application is handled. The only minor difference is that we WARN
on communication time out. Albeit not the most useful thing for a CLI
client, it could help overall user of lttng-sessiond in time out
situation.

Most call site already handled "unknown" error correctly. For those call
site we simply end up bringing more info in regards to the timeout
issue instead of mentioning that "-11" was returned.

Note, the reclamation of "app" is handled by the poll loop and
ust_app_unregister since the socket is shutdown by lttng-ust internally
on error, including EAGAIN.

Note that the application will try to register itself back to the
lttng-sessiond based on its configuration.

Known drawbacks
=========
None

Fixes: #1384

Signed-off-by: Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Change-Id: If364b5d48e7fd2b664276a0fb1b7eec2c45ed683
---
 src/bin/lttng-sessiond/ust-app.c      | 452 +++++++++++++++++++-------
 src/bin/lttng-sessiond/ust-consumer.c |  26 +-
 2 files changed, 356 insertions(+), 122 deletions(-)

diff --git a/src/bin/lttng-sessiond/ust-app.c b/src/bin/lttng-sessiond/ust-app.c
index efc82b052..5cd435164 100644
--- a/src/bin/lttng-sessiond/ust-app.c
+++ b/src/bin/lttng-sessiond/ust-app.c
@@ -280,9 +280,18 @@ void delete_ust_app_ctx(int sock, struct ust_app_ctx *ua_ctx,
 		pthread_mutex_lock(&app->sock_lock);
 		ret = ustctl_release_object(sock, ua_ctx->obj);
 		pthread_mutex_unlock(&app->sock_lock);
-		if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app sock %d release ctx obj handle %d failed with ret %d",
-					sock, ua_ctx->obj->handle, ret);
+		if (ret < 0) {
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("UST app release ctx failed. Application is dead (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app release ctx failed. Communication time out (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else {
+				ERR("UST app release ctx obj handle %d failed with ret %d (pid: %d, sock: %d).",
+						ua_ctx->obj->handle, ret,
+						app->pid, app->sock);
+			}
 		}
 		free(ua_ctx->obj);
 	}
@@ -308,9 +317,23 @@ void delete_ust_app_event(int sock, struct ust_app_event *ua_event,
 		pthread_mutex_lock(&app->sock_lock);
 		ret = ustctl_release_object(sock, ua_event->obj);
 		pthread_mutex_unlock(&app->sock_lock);
-		if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app sock %d release event obj failed with ret %d",
-					sock, ret);
+		if (ret < 0) {
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				/*
+				 * This is normal behavior, an application can
+				 * die during the creation process. Don't report
+				 * an error so the execution can continue
+				 * normally.
+				 */
+				DBG3("UST app release event failed. Application is dead (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app release event failed. Communication time out (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else {
+				ERR("UST app release event obj failed with ret %d (pid: %d, sock: %d).",
+						ret, app->pid, app->sock);
+			}
 		}
 		free(ua_event->obj);
 	}
@@ -333,9 +356,23 @@ static int release_ust_app_stream(int sock, struct ust_app_stream *stream,
 		pthread_mutex_lock(&app->sock_lock);
 		ret = ustctl_release_object(sock, stream->obj);
 		pthread_mutex_unlock(&app->sock_lock);
-		if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app sock %d release stream obj failed with ret %d",
-					sock, ret);
+		if (ret < 0) {
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				/*
+				 * This is normal behavior, an application can
+				 * die during the creation process. Don't report
+				 * an error so the execution can continue
+				 * normally.
+				 */
+				DBG3("UST app release stream failed. Application is dead (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app release stream failed. Communication time out (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else {
+				ERR("UST app release stream obj failed with ret %d (pid: %d, sock: %d).",
+						ret, app->pid, app->sock);
+			}
 		}
 		lttng_fd_put(LTTNG_FD_APPS, 2);
 		free(stream->obj);
@@ -501,9 +538,20 @@ void delete_ust_app_channel(int sock, struct ust_app_channel *ua_chan,
 		pthread_mutex_lock(&app->sock_lock);
 		ret = ustctl_release_object(sock, ua_chan->obj);
 		pthread_mutex_unlock(&app->sock_lock);
-		if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app sock %d release channel obj failed with ret %d",
-					sock, ret);
+		if (ret < 0) {
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("UST app channel %s release failed. Application is dead (pid: %d, sock: %d).",
+						ua_chan->name, app->pid,
+						app->sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app channel %s release failed. Communication time out (pid: %d, sock: %d).",
+						ua_chan->name, app->pid,
+						app->sock);
+			} else {
+				ERR("UST app channel %s release failed with ret %d (pid: %d, sock: %d).",
+						ua_chan->name, ret, app->pid,
+						app->sock);
+			}
 		}
 		lttng_fd_put(LTTNG_FD_APPS, 1);
 		free(ua_chan->obj);
@@ -866,10 +914,19 @@ void delete_ust_app_session(int sock, struct ust_app_session *ua_sess,
 		pthread_mutex_lock(&app->sock_lock);
 		ret = ustctl_release_handle(sock, ua_sess->handle);
 		pthread_mutex_unlock(&app->sock_lock);
-		if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app sock %d release session handle failed with ret %d",
-					sock, ret);
+		if (ret < 0) {
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("UST app release session handle failed. Application is dead (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app release session handle failed. Communication time out (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else {
+				ERR("UST app release session handle failed with ret %d (pid: %d, sock: %d).",
+						ret, app->pid, app->sock);
+			}
 		}
+
 		/* Remove session from application UST object descriptor. */
 		iter.iter.node = &ua_sess->ust_objd_node.node;
 		ret = lttng_ht_del(app->ust_sessions_objd, &iter);
@@ -1311,17 +1368,22 @@ int create_ust_channel_context(struct ust_app_channel *ua_chan,
 			ua_chan->obj, &ua_ctx->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app create channel context failed for app (pid: %d) "
-					"with ret %d", app->pid, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
-			 * This is normal behavior, an application can die during the
-			 * creation process. Don't report an error so the execution can
-			 * continue normally.
+			 * This is normal behavior, an application can die
+			 * during the creation process. Don't report an error so
+			 * the execution can continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app disable event failed. Application is dead.");
+			DBG3("UST app create channel context failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app create channel context failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app create channel context failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 		goto error;
 	}
@@ -1363,17 +1425,23 @@ int set_ust_event_filter(struct ust_app_event *ua_event,
 			ua_event->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app event %s filter failed for app (pid: %d) "
-					"with ret %d", ua_event->attr.name, app->pid, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app filter event failed. Application is dead.");
+			DBG3("UST app filter event failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app filter event failed. Communication timeout (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app event %s filter failed with ret %d (pid: %d, sock: %d).",
+					ua_event->attr.name, ret, app->pid,
+					app->sock);
 		}
 		goto error;
 	}
@@ -1434,17 +1502,23 @@ int set_ust_event_exclusion(struct ust_app_event *ua_event,
 	ret = ustctl_set_exclusion(app->sock, ust_exclusion, ua_event->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app event %s exclusions failed for app (pid: %d) "
-					"with ret %d", ua_event->attr.name, app->pid, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app event exclusion failed. Application is dead.");
+			DBG3("UST app event exclusion failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app event exclusion failed. Communication time out(pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app event %s exclusions failed with ret %d (pid: %d, sock: %d)",
+					ua_event->attr.name, ret, app->pid,
+					app->sock);
 		}
 		goto error;
 	}
@@ -1471,18 +1545,23 @@ static int disable_ust_event(struct ust_app *app,
 	ret = ustctl_disable(app->sock, ua_event->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app event %s disable failed for app (pid: %d) "
-					"and session handle %d with ret %d",
-					ua_event->attr.name, app->pid, ua_sess->handle, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app disable event failed. Application is dead.");
+			DBG3("UST app disable event failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app disable event failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app event %s disable failed, session handle %d, with ret %d (pid: %d, sock: %d)",
+					ua_event->attr.name, ua_sess->handle,
+					ret, app->pid, app->sock);
 		}
 		goto error;
 	}
@@ -1509,18 +1588,23 @@ static int disable_ust_channel(struct ust_app *app,
 	ret = ustctl_disable(app->sock, ua_chan->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app channel %s disable failed for app (pid: %d) "
-					"and session handle %d with ret %d",
-					ua_chan->name, app->pid, ua_sess->handle, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app disable channel failed. Application is dead.");
+			DBG3("UST app disable channel failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app disable channel failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app channel %s disable failed, session handle %d, with ret %d (pid: %d, sock: %d).",
+					ua_chan->name, ua_sess->handle, ret,
+					app->pid, app->sock);
 		}
 		goto error;
 	}
@@ -1547,18 +1631,23 @@ static int enable_ust_channel(struct ust_app *app,
 	ret = ustctl_enable(app->sock, ua_chan->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app channel %s enable failed for app (pid: %d) "
-					"and session handle %d with ret %d",
-					ua_chan->name, app->pid, ua_sess->handle, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app enable channel failed. Application is dead.");
+			DBG3("UST app channel %s enable failed. Application is dead (pid: %d, sock: %d).",
+					ua_chan->name, app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app channel %s enable failed. Communication time out (pid: %d, sock: %d).",
+					ua_chan->name, app->pid, app->sock);
+		} else {
+			ERR("UST app channel %s enable failed, session handle %d, with ret %d (pid: %d, sock: %d).",
+					ua_chan->name, ua_sess->handle, ret,
+					app->pid, app->sock);
 		}
 		goto error;
 	}
@@ -1587,18 +1676,23 @@ static int enable_ust_event(struct ust_app *app,
 	ret = ustctl_enable(app->sock, ua_event->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app event %s enable failed for app (pid: %d) "
-					"and session handle %d with ret %d",
-					ua_event->attr.name, app->pid, ua_sess->handle, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app enable event failed. Application is dead.");
+			DBG3("UST app enable event failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app enable event failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app enable event %s failed, session handle %d, with ret %d (pid: %d, sock: %d).",
+					ua_event->attr.name, ua_sess->handle,
+					ret, app->pid, app->sock);
 		}
 		goto error;
 	}
@@ -1636,6 +1730,13 @@ static int send_channel_pid_to_ust(struct ust_app *app,
 	if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 		ret = -ENOTCONN;	/* Caused by app exiting. */
 		goto error;
+	} else if (ret == -EAGAIN) {
+		/* Caused by timeout. */
+		WARN("Communication with application %d timed out on send_channel for channel \"%s\" of session \"%" PRIu64 "\".",
+				app->pid, ua_chan->name, ua_sess->tracing_id);
+		/* Treat this the same way as an application that is exiting. */
+		ret = -ENOTCONN;
+		goto error;
 	} else if (ret < 0) {
 		goto error;
 	}
@@ -1646,8 +1747,16 @@ static int send_channel_pid_to_ust(struct ust_app *app,
 	cds_list_for_each_entry_safe(stream, stmp, &ua_chan->streams.head, list) {
 		ret = ust_consumer_send_stream_to_ust(app, ua_chan, stream);
 		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
-			ret = -ENOTCONN;	/* Caused by app exiting. */
+			ret = -ENOTCONN; /* Caused by app exiting. */
 			goto error;
+		} else if (ret == -EAGAIN) {
+			/* Caused by timeout. */
+			WARN("Communication with application %d timed out on send_stream for stream \"%s\" of channel \"%s\" of session \"%" PRIu64 "\".",
+					app->pid, stream->name, ua_chan->name,
+					ua_sess->tracing_id);
+			/* Treat this the same way as an application that is
+			 * exiting. */
+			ret = -ENOTCONN;
 		} else if (ret < 0) {
 			goto error;
 		}
@@ -1682,17 +1791,23 @@ int create_ust_event(struct ust_app *app, struct ust_app_session *ua_sess,
 			&ua_event->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("Error ustctl create event %s for app pid: %d with ret %d",
-					ua_event->attr.name, app->pid, ret);
-		} else {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
 			ret = 0;
-			DBG3("UST app create event failed. Application is dead.");
+			DBG3("UST app create event failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			ret = 0;
+			WARN("UST app create event failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app create event %s failed with ret %d (pid: %d, sock: %d).",
+					ua_event->attr.name, ret, app->pid,
+					app->sock);
 		}
 		goto error;
 	}
@@ -2221,18 +2336,23 @@ static int create_ust_app_session(struct ltt_ust_session *usess,
 		ret = ustctl_create_session(app->sock);
 		pthread_mutex_unlock(&app->sock_lock);
 		if (ret < 0) {
-			if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-				ERR("Creating session for app pid %d with ret %d",
-						app->pid, ret);
-			} else {
-				DBG("UST app creating session failed. Application is dead");
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 				/*
 				 * This is normal behavior, an application can die during the
 				 * creation process. Don't report an error so the execution can
 				 * continue normally. This will get flagged ENOTCONN and the
 				 * caller will handle it.
 				 */
+				DBG("UST app creating session failed. Application is dead (pid: %d, sock: %d).",
+						app->pid, app->sock);
 				ret = 0;
+			} else if (ret == -EAGAIN) {
+				DBG("UST app creating session failed. Communication time out (pid: %d, sock: %d).",
+						app->pid, app->sock);
+				ret = 0;
+			} else {
+				ERR("UST app creating session failed with ret %d (pid: %d, sock:%d).",
+						ret, app->pid, app->sock);
 			}
 			delete_ust_app_session(-1, ua_sess, app);
 			if (ret != -ENOMEM) {
@@ -2814,6 +2934,13 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan,
 	if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 		ret = -ENOTCONN;	/* Caused by app exiting. */
 		goto error;
+	} else if (ret == -EAGAIN) {
+		/* Caused by timeout. */
+		WARN("Communication with application %d timed out on send_channel for channel \"%s\" of session \"%" PRIu64 "\".",
+				app->pid, ua_chan->name, ua_sess->tracing_id);
+		/* Treat this the same way as an application that is exiting. */
+		ret = -ENOTCONN;
+		goto error;
 	} else if (ret < 0) {
 		goto error;
 	}
@@ -2832,10 +2959,21 @@ static int send_channel_uid_to_ust(struct buffer_reg_channel *reg_chan,
 
 		ret = ust_consumer_send_stream_to_ust(app, ua_chan, &stream);
 		if (ret < 0) {
-			(void) release_ust_app_stream(-1, &stream, app);
 			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 				ret = -ENOTCONN; /* Caused by app exiting. */
+			} else if (ret == -EAGAIN) {
+				/*
+				 * Caused by timeout.
+				 * Treat this the same way as an application
+				 * that is exiting.
+				 */
+				WARN("Communication with application %d timed out on send_stream for stream \"%s\" of channel \"%s\" of session \"%" PRIu64 "\".",
+						app->pid, stream.name,
+						ua_chan->name,
+						ua_sess->tracing_id);
+				ret = -ENOTCONN;
 			}
+			(void) release_ust_app_stream(-1, &stream, app);
 			goto error_stream_unlock;
 		}
 
@@ -3487,10 +3625,15 @@ int ust_app_version(struct ust_app *app)
 	ret = ustctl_tracer_version(app->sock, &app->version);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
-			ERR("UST app %d version failed with ret %d", app->sock, ret);
+		if (ret == -LTTNG_UST_ERR_EXITING || ret == -EPIPE) {
+			DBG3("UST app version failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app version failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
 		} else {
-			DBG3("UST app %d version failed. Application is dead", app->sock);
+			ERR("UST app version failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 	}
 
@@ -3731,8 +3874,17 @@ int ust_app_list_events(struct lttng_event **events)
 		}
 		ret = ustctl_release_handle(app->sock, handle);
 		pthread_mutex_unlock(&app->sock_lock);
-		if (ret < 0 && ret != -LTTNG_UST_ERR_EXITING && ret != -EPIPE) {
-			ERR("Error releasing app handle for app %d with ret %d", app->sock, ret);
+		if (ret < 0) {
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("Error releasing app handle. Application died (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else if (ret == -EAGAIN) {
+				WARN("Error releasing app handle. Communication time out (pid: %d, sock: %d).",
+						app->pid, app->sock);
+			} else {
+				ERR("Error releasing app handle with ret %d (pid: %d, sock: %d).",
+						ret, app->pid, app->sock);
+			}
 		}
 	}
 
@@ -4460,18 +4612,25 @@ skip_setup:
 	ret = ustctl_start_session(app->sock, ua_sess->handle);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("Error starting tracing for app pid: %d (ret: %d)",
-					app->pid, ret);
-		} else {
-			DBG("UST app start session failed. Application is dead.");
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
+			DBG3("UST app start session failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
 			pthread_mutex_unlock(&ua_sess->lock);
 			goto end;
+		} else if (ret == -EAGAIN) {
+			WARN("UST app start session failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+			pthread_mutex_unlock(&ua_sess->lock);
+			goto end;
+
+		} else {
+			ERR("UST app start session failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 		goto error_unlock;
 	}
@@ -4487,9 +4646,17 @@ skip_setup:
 	pthread_mutex_lock(&app->sock_lock);
 	ret = ustctl_wait_quiescent(app->sock);
 	pthread_mutex_unlock(&app->sock_lock);
-	if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-		ERR("UST app wait quiescent failed for app pid %d ret %d",
-				app->pid, ret);
+	if (ret < 0) {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app wait quiescent failed. Application is dead (pid %d, sock: %d)",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app wait quiescent failed. Communication time out (pid %d, sock: %d)",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app wait quiescent failed with ret %d (pid %d, sock: %d)",
+					ret, app->pid, app->sock);
+		}
 	}
 
 end:
@@ -4551,17 +4718,23 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
 	ret = ustctl_stop_session(app->sock, ua_sess->handle);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("Error stopping tracing for app pid: %d (ret: %d)",
-					app->pid, ret);
-		} else {
-			DBG("UST app stop session failed. Application is dead.");
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
 			/*
 			 * This is normal behavior, an application can die during the
 			 * creation process. Don't report an error so the execution can
 			 * continue normally.
 			 */
+			DBG3("UST app stop session failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
 			goto end_unlock;
+		} else if (ret == -EAGAIN) {
+			WARN("UST app stop session failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
+			goto end_unlock;
+
+		} else {
+			ERR("UST app stop session failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 		goto error_rcu_unlock;
 	}
@@ -4572,9 +4745,17 @@ int ust_app_stop_trace(struct ltt_ust_session *usess, struct ust_app *app)
 	pthread_mutex_lock(&app->sock_lock);
 	ret = ustctl_wait_quiescent(app->sock);
 	pthread_mutex_unlock(&app->sock_lock);
-	if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-		ERR("UST app wait quiescent failed for app pid %d ret %d",
-				app->pid, ret);
+	if (ret < 0) {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app wait quiescent failed. Application is dead (pid %d, sock: %d)",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app wait quiescent failed. Communication time out (pid %d, sock: %d)",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app wait quiescent failed with ret %d (pid %d, sock: %d)",
+					ret, app->pid, app->sock);
+		}
 	}
 
 	health_code_update();
@@ -4922,9 +5103,17 @@ static int destroy_trace(struct ltt_ust_session *usess, struct ust_app *app)
 	pthread_mutex_lock(&app->sock_lock);
 	ret = ustctl_wait_quiescent(app->sock);
 	pthread_mutex_unlock(&app->sock_lock);
-	if (ret < 0 && ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-		ERR("UST app wait quiescent failed for app pid %d ret %d",
-				app->pid, ret);
+	if (ret < 0) {
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app wait quiescent failed. Application is dead (pid %d, sock: %d)",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app wait quiescent failed. Communication time out (pid %d, sock: %d)",
+					app->pid, app->sock);
+		} else {
+			ERR("UST app wait quiescent failed with ret %d (pid %d, sock: %d)",
+					ret, app->pid, app->sock);
+		}
 	}
 end:
 	rcu_read_unlock();
@@ -5494,10 +5683,15 @@ reply:
 
 	ret = ustctl_reply_register_channel(sock, chan_id, type, ret_code);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app reply channel failed with ret %d", ret);
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app reply channel failed. Application died (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app reply channel failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
 		} else {
-			DBG3("UST app reply channel failed. Application died");
+			ERR("UST app reply channel failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 		goto error;
 	}
@@ -5591,10 +5785,15 @@ static int add_event_ust_registry(int sock, int sobjd, int cobjd, char *name,
 	 */
 	ret = ustctl_reply_register_event(sock, event_id, ret_code);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app reply event failed with ret %d", ret);
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app reply event failed. Application died (pid: %d, sock: %d.",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app reply event failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
 		} else {
-			DBG3("UST app reply event failed. Application died");
+			ERR("UST app reply event failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 		/*
 		 * No need to wipe the create event since the application socket will
@@ -5679,10 +5878,15 @@ static int add_enum_ust_registry(int sock, int sobjd, char *name,
 	 */
 	ret = ustctl_reply_register_enum(sock, enum_id, ret_code);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app reply enum failed with ret %d", ret);
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app reply enum failed. Application died (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app reply enum failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
 		} else {
-			DBG3("UST app reply enum failed. Application died");
+			ERR("UST app reply enum failed with ret %d (pid: %d, sock: %d).",
+					ret, app->pid, app->sock);
 		}
 		/*
 		 * No need to wipe the create enum since the application socket will
@@ -5714,10 +5918,15 @@ int ust_app_recv_notify(int sock)
 
 	ret = ustctl_recv_notify(sock, &cmd);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("UST app recv notify failed with ret %d", ret);
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app recv notify failed. Application died (sock: %d).",
+					sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app recv notify failed. Communication time out (sock: %d).",
+					sock);
 		} else {
-			DBG3("UST app recv notify failed. Application died");
+			ERR("UST app recv notify failed with ret %d (sock: %d).",
+					ret, sock);
 		}
 		goto error;
 	}
@@ -5736,10 +5945,15 @@ int ust_app_recv_notify(int sock)
 				&loglevel_value, &sig, &nr_fields, &fields,
 				&model_emf_uri);
 		if (ret < 0) {
-			if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-				ERR("UST app recv event failed with ret %d", ret);
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("UST app recv event failed. Application died (sock: %d).",
+						sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app recv event failed. Communication time out (sock: %d).",
+						sock);
 			} else {
-				DBG3("UST app recv event failed. Application died");
+				ERR("UST app recv event failed with ret %d (sock: %d)",
+						ret, sock);
 			}
 			goto error;
 		}
@@ -5769,10 +5983,15 @@ int ust_app_recv_notify(int sock)
 		ret = ustctl_recv_register_channel(sock, &sobjd, &cobjd, &nr_fields,
 				&fields);
 		if (ret < 0) {
-			if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-				ERR("UST app recv channel failed with ret %d", ret);
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("UST app recv channel failed. Application died (sock: %d).",
+						sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app recv channel failed. Communication time out (sock: %d).",
+						sock);
 			} else {
-				DBG3("UST app recv channel failed. Application died");
+				ERR("UST app recv channel failed with ret %d (sock: %d)",
+						ret, sock);
 			}
 			goto error;
 		}
@@ -5802,10 +6021,15 @@ int ust_app_recv_notify(int sock)
 		ret = ustctl_recv_register_enum(sock, &sobjd, name,
 				&entries, &nr_entries);
 		if (ret < 0) {
-			if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-				ERR("UST app recv enum failed with ret %d", ret);
+			if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+				DBG3("UST app recv enum failed. Application died (sock: %d).",
+						sock);
+			} else if (ret == -EAGAIN) {
+				WARN("UST app recv enum failed. Communication time out (sock: %d).",
+						sock);
 			} else {
-				DBG3("UST app recv enum failed. Application died");
+				ERR("UST app recv enum failed with ret %d (sock: %d)",
+						ret, sock);
 			}
 			goto error;
 		}
diff --git a/src/bin/lttng-sessiond/ust-consumer.c b/src/bin/lttng-sessiond/ust-consumer.c
index 8dc0fd905..5504ceb19 100644
--- a/src/bin/lttng-sessiond/ust-consumer.c
+++ b/src/bin/lttng-sessiond/ust-consumer.c
@@ -413,11 +413,16 @@ int ust_consumer_send_stream_to_ust(struct ust_app *app,
 	ret = ustctl_send_stream_to_ust(app->sock, channel->obj, stream->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("ustctl send stream handle %d to app pid: %d with ret %d",
-					stream->obj->handle, app->pid, ret);
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app send stream to ust failed. Application is dead. (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app send stream to ust failed. Communication time out (pid: %d, sock: %d).",
+					app->pid, app->sock);
 		} else {
-			DBG3("UST app send stream to ust failed. Application is dead.");
+			ERR("UST app send stream, handle %d, to ust failed with ret %d (pid: %d, sock: %d).",
+					stream->obj->handle, ret, app->pid,
+					app->sock);
 		}
 		goto error;
 	}
@@ -450,11 +455,16 @@ int ust_consumer_send_channel_to_ust(struct ust_app *app,
 	ret = ustctl_send_channel_to_ust(app->sock, ua_sess->handle, channel->obj);
 	pthread_mutex_unlock(&app->sock_lock);
 	if (ret < 0) {
-		if (ret != -EPIPE && ret != -LTTNG_UST_ERR_EXITING) {
-			ERR("Error ustctl send channel %s to app pid: %d with ret %d",
-					channel->name, app->pid, ret);
+		if (ret == -EPIPE || ret == -LTTNG_UST_ERR_EXITING) {
+			DBG3("UST app send channel to ust failed. Application is dead (pid: %d, sock: %d).",
+					app->pid, app->sock);
+		} else if (ret == -EAGAIN) {
+			WARN("UST app send channel to ust failed. Communication timeout (pid: %d, sock: %d).",
+					app->pid, app->sock);
 		} else {
-			DBG3("UST app send channel to ust failed. Application is dead.");
+			ERR("UST·app·send·channel %s, to·ust·failed with ret %d (pid: %d, sock: %d).",
+					channel->name, ret, app->pid,
+					app->sock);
 		}
 		goto error;
 	}
-- 
2.25.1

