From 19280319c7ce2dfa9710a67ee2570d958a4fac9c Mon Sep 17 00:00:00 2001
From: Nikolay Shirokovskiy <nshirokovskiy@tarantool.org>
Date: Wed, 4 Oct 2023 18:36:25 +0300
Subject: [PATCH] fiber: mark stack slab leak on mprotect fail as a non-leak

With new ASAN-friendly small implementation unit/fiber_stack.c test
start to fail. The issue is leak sanitizer reports a leak. This is an
expected leak of test for mprotect failure on fiber stack destruction.
Let's tell sanitizer to ignore this case.

By the way let's drop test code for temporary redirecting stderr. It is
outdated as test is TAP-compatible. It was a PITA as due to this
redirection there was no leak report only error exit code.

Part of #7327

NO_CHANGELOG=internal
NO_DOC=internal

(cherry picked from commit 41844ffbb59fdaeff2fcd9909e9f5ddd525f5c3f)
---
 src/lib/core/fiber.c    |  8 ++++++++
 src/trivia/util.h       |  7 +++++++
 test/unit/fiber_stack.c | 12 ------------
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c
index d130e7dbe9..ec0ede477b 100644
--- a/src/lib/core/fiber.c
+++ b/src/lib/core/fiber.c
@@ -1338,6 +1338,14 @@ fiber_stack_destroy(struct fiber *fiber, struct slab_cache *slabc)
 			 */
 			say_syserror("fiber: Can't put guard page to slab. "
 				     "Leak %zu bytes", (size_t)fiber->stack_size);
+			/*
+			 * Suppress memory leak report for this object.
+			 *
+			 * Works even though it is not a beginning of
+			 * allocation (there is ASAN slab cache allocation
+			 * header).
+			 */
+			LSAN_IGNORE_OBJECT(fiber->stack_slab);
 		} else {
 			slab_put(slabc, fiber->stack_slab);
 		}
diff --git a/src/trivia/util.h b/src/trivia/util.h
index cf421173db..2ceec8a962 100644
--- a/src/trivia/util.h
+++ b/src/trivia/util.h
@@ -756,6 +756,13 @@ illegal_instruction(void)
 }
 #endif
 
+#ifdef ENABLE_ASAN
+# include <sanitizer/lsan_interface.h>
+# define LSAN_IGNORE_OBJECT(ptr) __lsan_ignore_object(ptr)
+#else
+# define LSAN_IGNORE_OBJECT(ptr) ((void)ptr)
+#endif
+
 #if defined(__cplusplus)
 } /* extern "C" */
 #endif /* defined(__cplusplus) */
diff --git a/test/unit/fiber_stack.c b/test/unit/fiber_stack.c
index 462540762c..9cd9b53199 100644
--- a/test/unit/fiber_stack.c
+++ b/test/unit/fiber_stack.c
@@ -44,10 +44,6 @@ main_f(va_list ap)
 	 * gh-9026. Stack size crafted to be close to 64k so we should
 	 * hit red zone around stack when writing watermark if bug is not
 	 * fixed.
-	 *
-	 * The test is placed at the beginning because stderr is redirected
-	 * to /dev/null at the end of the test and ASAN diagnostic will
-	 * not be visible if the test will be placed at the end.
 	 */
 	fiber_attr = fiber_attr_new();
 	fiber_attr_setstacksize(fiber_attr, (64 << 10) - 128);
@@ -130,17 +126,9 @@ main_f(va_list ap)
 	inj = errinj(ERRINJ_FIBER_MPROTECT, ERRINJ_INT);
 	inj->iparam = PROT_READ | PROT_WRITE;
 
-	/* On fiber_mprotect() fail we are logging number of bytes to be
-	 * leaked. However, it depends on system page_size (_SC_PAGESIZE).
-	 * On different OS's this parameter may vary. So let's temporary
-	 * redirect stderr to dev/null to make this test stable regardless
-	 * of OS.
-	 */
-	freopen("/dev/null", "w", stderr);
 	fiber_start(fiber);
 	fiber_join(fiber);
 	inj->iparam = -1;
-	freopen("/dev/stderr", "w", stderr);
 
 	used_after = slabc->allocated.stats.used;
 	ok(used_after > used_before, "expected leak detected");
-- 
GitLab