[lttng-dev] [PATCH v2 lttng-tools] Add return code to the testpoint mechanism

Christian Babeux christian.babeux at efficios.com
Mon Dec 10 15:38:39 EST 2012


The testpoint processing could fail and currently there is no mechanism
to notify the caller of such failures. This patch adds an int return code
to the testpoint prototype. Non-zero return code indicate failure.

When using the testpoint mechanism, the caller should properly handle
testpoint failure cases and trigger the appropriate response
(error handling, thread teardown, etc.).

Signed-off-by: Christian Babeux <christian.babeux at efficios.com>
---
 src/bin/lttng-sessiond/main.c     | 44 ++++++++++++++++++++++++++++-----------
 src/common/testpoint/testpoint.h  | 20 +++++++++---------
 tests/tools/health/health_exit.c  | 20 +++++++++++++-----
 tests/tools/health/health_stall.c | 12 ++++++++---
 4 files changed, 66 insertions(+), 30 deletions(-)

diff --git a/src/bin/lttng-sessiond/main.c b/src/bin/lttng-sessiond/main.c
index d5cfc0e..6110ee9 100644
--- a/src/bin/lttng-sessiond/main.c
+++ b/src/bin/lttng-sessiond/main.c
@@ -689,14 +689,14 @@ static void *thread_manage_kernel(void *data)
 	char tmp;
 	struct lttng_poll_event events;
 
-	DBG("Thread manage kernel started");
+	DBG("[thread] Thread manage kernel started");
 
-	testpoint(thread_manage_kernel);
+	if (testpoint(thread_manage_kernel)) {
+		goto error_testpoint;
+	}
 
 	health_code_update(&health_thread_kernel);
 
-	testpoint(thread_manage_kernel_before_loop);
-
 	ret = create_thread_poll_set(&events, 2);
 	if (ret < 0) {
 		goto error_poll_create;
@@ -707,6 +707,10 @@ static void *thread_manage_kernel(void *data)
 		goto error;
 	}
 
+	if (testpoint(thread_manage_kernel_before_loop)) {
+		goto error;
+	}
+
 	while (1) {
 		health_code_update(&health_thread_kernel);
 
@@ -794,6 +798,7 @@ exit:
 error:
 	lttng_poll_clean(&events);
 error_poll_create:
+error_testpoint:
 	utils_close_pipe(kernel_poll_pipe);
 	kernel_poll_pipe[0] = kernel_poll_pipe[1] = -1;
 	if (err) {
@@ -889,7 +894,9 @@ static void *thread_manage_consumer(void *data)
 restart:
 	health_poll_update(&consumer_data->health);
 
-	testpoint(thread_manage_consumer);
+	if (testpoint(thread_manage_consumer)) {
+		goto error;
+	}
 
 	ret = lttng_poll_wait(&events, -1);
 	health_poll_update(&consumer_data->health);
@@ -1093,11 +1100,13 @@ static void *thread_manage_apps(void *data)
 
 	DBG("[thread] Manage application started");
 
-	testpoint(thread_manage_apps);
-
 	rcu_register_thread();
 	rcu_thread_online();
 
+	if (testpoint(thread_manage_apps)) {
+		goto error_testpoint;
+	}
+
 	health_code_update(&health_thread_app_manage);
 
 	ret = create_thread_poll_set(&events, 2);
@@ -1110,7 +1119,9 @@ static void *thread_manage_apps(void *data)
 		goto error;
 	}
 
-	testpoint(thread_manage_apps_before_loop);
+	if (testpoint(thread_manage_apps_before_loop)) {
+		goto error;
+	}
 
 	health_code_update(&health_thread_app_manage);
 
@@ -1250,6 +1261,7 @@ exit:
 error:
 	lttng_poll_clean(&events);
 error_poll_create:
+error_testpoint:
 	utils_close_pipe(apps_cmd_pipe);
 	apps_cmd_pipe[0] = apps_cmd_pipe[1] = -1;
 
@@ -1358,7 +1370,9 @@ static void *thread_registration_apps(void *data)
 
 	DBG("[thread] Manage application registration started");
 
-	testpoint(thread_registration_apps);
+	if (testpoint(thread_registration_apps)) {
+		goto error_testpoint;
+	}
 
 	ret = lttcomm_listen_unix_sock(apps_sock);
 	if (ret < 0) {
@@ -1537,6 +1551,7 @@ error_poll_add:
 	lttng_poll_clean(&events);
 error_listen:
 error_create_poll:
+error_testpoint:
 	DBG("UST Registration thread cleanup complete");
 
 	return NULL;
@@ -3122,10 +3137,12 @@ static void *thread_manage_clients(void *data)
 
 	DBG("[thread] Manage client started");
 
-	testpoint(thread_manage_clients);
-
 	rcu_register_thread();
 
+	if (testpoint(thread_manage_clients)) {
+		goto error_testpoint;
+	}
+
 	health_code_update(&health_thread_cmd);
 
 	ret = lttcomm_listen_unix_sock(client_sock);
@@ -3155,7 +3172,9 @@ static void *thread_manage_clients(void *data)
 		kill(ppid, SIGUSR1);
 	}
 
-	testpoint(thread_manage_clients_before_loop);
+	if (testpoint(thread_manage_clients_before_loop)) {
+		goto error;
+	}
 
 	health_code_update(&health_thread_cmd);
 
@@ -3330,6 +3349,7 @@ error:
 
 error_listen:
 error_create_poll:
+error_testpoint:
 	unlink(client_unix_sock_path);
 	if (client_sock >= 0) {
 		ret = close(client_sock);
diff --git a/src/common/testpoint/testpoint.h b/src/common/testpoint/testpoint.h
index ba3af8a..dc5be83 100644
--- a/src/common/testpoint/testpoint.h
+++ b/src/common/testpoint/testpoint.h
@@ -31,38 +31,38 @@ void *lttng_testpoint_lookup(const char *name);
 /*
  * Testpoint is only active if the global lttng_testpoint_activated flag is
  * set.
+ * Return a non-zero error code to indicate failure.
  */
-#define testpoint(name)					\
-	do {							\
-		if (caa_unlikely(lttng_testpoint_activated)) {	\
-			__testpoint_##name##_wrapper();		\
-		}						\
-	} while (0)
+#define testpoint(name)				\
+	((caa_unlikely(lttng_testpoint_activated))	\
+	? __testpoint_##name##_wrapper() : 0)
 
 /*
  * One wrapper per testpoint is generated. This is to keep track of the symbol
  * lookup status and the corresponding function pointer, if any.
  */
 #define _TESTPOINT_DECL(_name)						\
-	static inline void __testpoint_##_name##_wrapper(void)		\
+	static inline int __testpoint_##_name##_wrapper(void)		\
 	{								\
-		static void (*tp)(void);				\
+		int ret = 0;						\
+		static int (*tp)(void);					\
 		static int found;					\
 		const char *tp_name = "__testpoint_" #_name;		\
 									\
 		if (tp) {						\
-			tp();						\
+			ret = tp();					\
 		} else {						\
 			if (!found) {					\
 				tp = lttng_testpoint_lookup(tp_name);	\
 				if (tp) {				\
 					found = 1;			\
-					tp();				\
+					ret = tp();			\
 				} else {				\
 					found = -1;			\
 				}					\
 			}						\
 		}							\
+		return ret;						\
 	}
 
 /* Testpoint declaration */
diff --git a/tests/tools/health/health_exit.c b/tests/tools/health/health_exit.c
index 258b08d..8e41405 100644
--- a/tests/tools/health/health_exit.c
+++ b/tests/tools/health/health_exit.c
@@ -35,47 +35,57 @@ int check_env_var(const char *env)
 	return 0;
 }
 
-void __testpoint_thread_manage_clients(void)
+int __testpoint_thread_manage_clients(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_EXIT";
 
 	if (check_env_var(var)) {
 		pthread_exit(NULL);
 	}
+
+	return 0;
 }
 
-void __testpoint_thread_registration_apps(void)
+int __testpoint_thread_registration_apps(void)
 {
 	const char *var = "LTTNG_THREAD_REG_APPS_EXIT";
 
 	if (check_env_var(var)) {
 		pthread_exit(NULL);
 	}
+
+	return 0;
 }
 
-void __testpoint_thread_manage_apps(void)
+int __testpoint_thread_manage_apps(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_APPS_EXIT";
 
 	if (check_env_var(var)) {
 		pthread_exit(NULL);
 	}
+
+	return 0;
 }
 
-void __testpoint_thread_manage_kernel(void)
+int __testpoint_thread_manage_kernel(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_KERNEL_EXIT";
 
 	if (check_env_var(var)) {
 		pthread_exit(NULL);
 	}
+
+	return 0;
 }
 
-void __testpoint_thread_manage_consumer(void)
+int __testpoint_thread_manage_consumer(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_CONSUMER_EXIT";
 
 	if (check_env_var(var)) {
 		pthread_exit(NULL);
 	}
+
+	return 0;
 }
diff --git a/tests/tools/health/health_stall.c b/tests/tools/health/health_stall.c
index 38fe5f8..127f5fc 100644
--- a/tests/tools/health/health_stall.c
+++ b/tests/tools/health/health_stall.c
@@ -38,7 +38,7 @@ int check_env_var(const char *env)
 	return 0;
 }
 
-void __testpoint_thread_manage_clients_before_loop(void)
+int __testpoint_thread_manage_clients_before_loop(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_CLIENTS_STALL";
 
@@ -48,9 +48,11 @@ void __testpoint_thread_manage_clients_before_loop(void)
 			sleep_time = sleep(sleep_time);
 		}
 	}
+
+	return 0;
 }
 
-void __testpoint_thread_manage_kernel_before_loop(void)
+int __testpoint_thread_manage_kernel_before_loop(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_KERNEL_STALL";
 
@@ -60,9 +62,11 @@ void __testpoint_thread_manage_kernel_before_loop(void)
 			sleep_time = sleep(sleep_time);
 		}
 	}
+
+	return 0;
 }
 
-void __testpoint_thread_manage_apps_before_loop(void)
+int __testpoint_thread_manage_apps_before_loop(void)
 {
 	const char *var = "LTTNG_THREAD_MANAGE_APPS_STALL";
 
@@ -72,4 +76,6 @@ void __testpoint_thread_manage_apps_before_loop(void)
 			sleep_time = sleep(sleep_time);
 		}
 	}
+
+	return 0;
 }
-- 
1.8.0.1




More information about the lttng-dev mailing list