Tarantool development patches archive
 help / color / mirror / Atom feed
From: Egor Elchinov via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: tarantool-patches@dev.tarantool.org
Cc: gorcunov@tarantool.org
Subject: [Tarantool-patches] [PATCH 5/7] fiber: add dynamic option for parent backtrace
Date: Thu,  1 Jul 2021 18:54:48 +0300
Message-ID: <202247f05706af029e37cff627542cc4d6dda4f7.1625153622.git.elchinov.es@gmail.com> (raw)
In-Reply-To: <cover.1625153622.git.elchinov.es@gmail.com>

From: Egor Elchinov <eelchinov@tarantool.org>

This patch adds option enabling to turn on and off
the collection of backtraces of parent fibers when
creating new fibers.

Needed for: #4002

@TarantoolBot document
Title: new option for fiber parent backtrace

`fiber.parent_bt_enable()` and `fiber.parent_bt_disable()`
turn on and off the ability to trace fiber creation stacks.
If present this option may cause up to 40 per cent
slowdown of fiber creation.
By default parent backtrace is disabled.

Note that fibers created while this option was disabled
lack their parent backtraces in `fiber.info()` forever.
---
 src/lib/core/fiber.c                          | 29 ++++++++-
 src/lib/core/fiber.h                          | 11 ++++
 src/lua/fiber.c                               | 62 +++++++++++++------
 .../gh-4002-fiber-creation-backtrace.result   | 21 +++++++
 .../gh-4002-fiber-creation-backtrace.test.lua |  7 +++
 5 files changed, 110 insertions(+), 20 deletions(-)

diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c
index 924ff3c82..dd26e2f13 100644
--- a/src/lib/core/fiber.c
+++ b/src/lib/core/fiber.c
@@ -220,6 +220,10 @@ fiber_mprotect(void *addr, size_t len, int prot)
 static __thread bool fiber_top_enabled = false;
 #endif /* ENABLE_FIBER_TOP */
 
+#if ENABLE_BACKTRACE
+static __thread bool fiber_parent_bt_enabled = false;
+#endif /* ENABLE_BACKTRACE */
+
 /**
  * An action performed each time a context switch happens.
  * Used to count each fiber's processing time.
@@ -1265,7 +1269,10 @@ fiber_new_ex(const char *name, const struct fiber_attr *fiber_attr,
 	fiber->fid = cord->next_fid;
 	fiber_set_name(fiber, name);
 #if ENABLE_BACKTRACE
-	backtrace_collect_ip(fiber->parent_bt_ip_buf, FIBER_PARENT_BT_MAX);
+	if (fiber_parent_bt_enabled) {
+		backtrace_collect_ip(fiber->parent_bt_ip_buf,
+				     FIBER_PARENT_BT_MAX);
+	}
 #endif /* ENABLE_BACKTRACE */
 	register_fid(fiber);
 	fiber->csw = 0;
@@ -1414,6 +1421,26 @@ fiber_top_disable(void)
 }
 #endif /* ENABLE_FIBER_TOP */
 
+#if ENABLE_BACKTRACE
+bool
+fiber_parent_bt_is_enabled(void)
+{
+	return fiber_parent_bt_enabled;
+}
+
+void
+fiber_parent_bt_enable(void)
+{
+	fiber_parent_bt_enabled = true;
+}
+
+void
+fiber_parent_bt_disable(void)
+{
+	fiber_parent_bt_enabled = false;
+}
+#endif /* ENABLE_BACKTRACE */
+
 size_t
 box_region_used(void)
 {
diff --git a/src/lib/core/fiber.h b/src/lib/core/fiber.h
index ce1c83d11..477b68e4c 100644
--- a/src/lib/core/fiber.h
+++ b/src/lib/core/fiber.h
@@ -878,6 +878,17 @@ void
 fiber_top_disable(void);
 #endif /* ENABLE_FIBER_TOP */
 
+#if ENABLE_BACKTRACE
+bool
+fiber_parent_bt_is_enabled(void);
+
+void
+fiber_parent_bt_enable(void);
+
+void
+fiber_parent_bt_disable(void);
+#endif /* ENABLE_BACKTRACE */
+
 /** Useful for C unit tests */
 static inline int
 fiber_c_invoke(fiber_func f, va_list ap)
diff --git a/src/lua/fiber.c b/src/lua/fiber.c
index 026e30bc6..fe01ae23b 100644
--- a/src/lua/fiber.c
+++ b/src/lua/fiber.c
@@ -205,7 +205,7 @@ struct lua_parent_tb_ctx {
 	int tb_frame;
 };
 
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 static void
 dump_lua_frame(struct lua_State *L, lua_Debug *ar, int tb_frame)
 {
@@ -433,7 +433,7 @@ lbox_fiber_statof_map(struct fiber *f, void *cb_ctx, bool backtrace)
 	lua_settable(L, -3);
 
 	if (backtrace) {
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 		struct lua_fiber_tb_ctx tb_ctx;
 		struct lua_parent_tb_ctx parent_tb_ctx;
 		tb_ctx.L = L;
@@ -446,15 +446,18 @@ lbox_fiber_statof_map(struct fiber *f, void *cb_ctx, bool backtrace)
 				  f != fiber() ? &f->ctx : NULL, &tb_ctx);
 		lua_settable(L, -3);
 
-		parent_tb_ctx.L = L;
-		parent_tb_ctx.bt = f->storage.lua.parent_bt;
-		parent_tb_ctx.tb_frame = 0;
-		lua_pushstring(L, "backtrace_parent");
-		lua_newtable(L);
-		backtrace_foreach_ip(fiber_parent_backtrace_cb,
-				     f->parent_bt_ip_buf,
-				     FIBER_PARENT_BT_MAX, &parent_tb_ctx);
-		lua_settable(L, -3);
+		if (fiber_parent_bt_is_enabled()) {
+			parent_tb_ctx.L = L;
+			parent_tb_ctx.bt = f->storage.lua.parent_bt;
+			parent_tb_ctx.tb_frame = 0;
+			lua_pushstring(L, "backtrace_parent");
+			lua_newtable(L);
+			backtrace_foreach_ip(fiber_parent_backtrace_cb,
+					     f->parent_bt_ip_buf,
+					     FIBER_PARENT_BT_MAX, 
+					     &parent_tb_ctx);
+			lua_settable(L, -3);
+		}
 #endif /* ENABLE_BACKTRACE */
 	}
 	return 0;
@@ -471,7 +474,7 @@ lbox_fiber_statof(struct fiber *f, void *cb_ctx, bool backtrace)
 	return 0;
 }
 
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 static int
 lbox_fiber_statof_bt(struct fiber *f, void *cb_ctx)
 {
@@ -560,7 +563,7 @@ lbox_fiber_top_disable(struct lua_State *L)
 }
 #endif /* ENABLE_FIBER_TOP */
 
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 bool
 lbox_do_backtrace(struct lua_State *L)
 {
@@ -578,6 +581,22 @@ lbox_do_backtrace(struct lua_State *L)
 	}
 	return true;
 }
+
+static int
+lbox_fiber_parent_bt_enable(struct lua_State *L)
+{
+	(void) L;
+	fiber_parent_bt_enable();
+	return 0;
+}
+
+static int
+lbox_fiber_parent_bt_disable(struct lua_State *L)
+{
+	(void) L;
+	fiber_parent_bt_disable();
+	return 0;
+}
 #endif /* ENABLE_BACKTRACE */
 
 /**
@@ -586,7 +605,7 @@ lbox_do_backtrace(struct lua_State *L)
 static int
 lbox_fiber_info(struct lua_State *L)
 {
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 	bool do_backtrace = lbox_do_backtrace(L);
 	if (do_backtrace) {
 		lua_newtable(L);
@@ -621,7 +640,7 @@ lua_fiber_run_f(MAYBE_UNUSED va_list ap)
 	if (f->flags & FIBER_IS_JOINABLE) {
 		lua_pushinteger(L, coro_ref);
 	} else {
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 		fiber_parent_bt_free(f);
 #endif
 		luaL_unref(L, LUA_REGISTRYINDEX, coro_ref);
@@ -647,9 +666,10 @@ fiber_create(struct lua_State *L)
 		luaT_error(L);
 	}
 
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 	// TODO: error handling
-	fiber_parent_bt_init(f, L);
+	if (fiber_parent_bt_is_enabled())
+		fiber_parent_bt_init(f, L);
 #endif
 
 	/* Move the arguments to the new coro */
@@ -748,7 +768,7 @@ lbox_fiber_object_info(struct lua_State *L)
 	struct fiber *f = lbox_get_fiber(L);
 	if (f == NULL)
 		luaL_error(L, "the fiber is dead");
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 	bool do_backtrace = lbox_do_backtrace(L);
 	if (do_backtrace) {
 		lua_newtable(L);
@@ -1033,7 +1053,7 @@ lbox_fiber_join(struct lua_State *L)
 		}
 	}
 	if (child_L != NULL) {
-#ifdef ENABLE_BACKTRACE
+#if ENABLE_BACKTRACE
 		fiber_parent_bt_free(fiber);
 #endif
 		luaL_unref(L, LUA_REGISTRYINDEX, coro_ref);
@@ -1091,6 +1111,10 @@ static const struct luaL_Reg fiberlib[] = {
 	{"top_enable", lbox_fiber_top_enable},
 	{"top_disable", lbox_fiber_top_disable},
 #endif /* ENABLE_FIBER_TOP */
+#if ENABLE_BACKTRACE
+	{"parent_bt_enable", lbox_fiber_parent_bt_enable},
+	{"parent_bt_disable", lbox_fiber_parent_bt_disable},
+#endif /* ENABLE_BACKTRACE */
 	{"sleep", lbox_fiber_sleep},
 	{"yield", lbox_fiber_yield},
 	{"self", lbox_fiber_self},
diff --git a/test/app/gh-4002-fiber-creation-backtrace.result b/test/app/gh-4002-fiber-creation-backtrace.result
index 4934b82d6..6a075911d 100644
--- a/test/app/gh-4002-fiber-creation-backtrace.result
+++ b/test/app/gh-4002-fiber-creation-backtrace.result
@@ -47,6 +47,17 @@ baz = function(n) bar(n) end
  | ---
  | ...
 
+baz(10)
+ | ---
+ | ...
+assert(parent_stack_len == -1)
+ | ---
+ | - true
+ | ...
+
+if stack_len ~= -1 then fiber:parent_bt_enable() end
+ | ---
+ | ...
 baz(10)
  | ---
  | ...
@@ -55,3 +66,13 @@ assert(parent_stack_len > 0 or stack_len == -1)
  | - true
  | ...
 
+if stack_len ~= -1 then fiber:parent_bt_disable() end
+ | ---
+ | ...
+baz(10)
+ | ---
+ | ...
+assert(parent_stack_len == -1)
+ | ---
+ | - true
+ | ...
diff --git a/test/app/gh-4002-fiber-creation-backtrace.test.lua b/test/app/gh-4002-fiber-creation-backtrace.test.lua
index 24d41a860..79a516860 100644
--- a/test/app/gh-4002-fiber-creation-backtrace.test.lua
+++ b/test/app/gh-4002-fiber-creation-backtrace.test.lua
@@ -22,6 +22,13 @@ local bar,baz
 bar = function(n) if n ~= 0 then baz(n-1) else fiber.create(foo) end end
 baz = function(n) bar(n) end
 
+baz(10)
+assert(parent_stack_len == -1)
+
+if stack_len ~= -1 then fiber:parent_bt_enable() end
 baz(10)
 assert(parent_stack_len > 0 or stack_len == -1)
 
+if stack_len ~= -1 then fiber:parent_bt_disable() end
+baz(10)
+assert(parent_stack_len == -1)
-- 
2.31.1


  parent reply	other threads:[~2021-07-01 15:57 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-01 15:54 [Tarantool-patches] [PATCH 0/7] fiber: introduce creation backtrace Egor Elchinov via Tarantool-patches
2021-07-01 15:54 ` [Tarantool-patches] [PATCH 1/7] fiber: add PoC for fiber " Egor Elchinov via Tarantool-patches
2021-07-01 15:54 ` [Tarantool-patches] [PATCH 2/7] fiber: fix DARWIN build Egor Elchinov via Tarantool-patches
2021-07-01 15:54 ` [Tarantool-patches] [PATCH 3/7] fiber: apply fix patch Egor Elchinov via Tarantool-patches
2021-07-01 15:54 ` [Tarantool-patches] [PATCH 4/7] fiber: add PoC for Lua parent backtrace Egor Elchinov via Tarantool-patches
2021-07-01 15:54 ` Egor Elchinov via Tarantool-patches [this message]
2021-07-01 15:54 ` [Tarantool-patches] [PATCH 6/7] fiber: refactor lua backtrace routine Egor Elchinov via Tarantool-patches
2021-07-01 15:54 ` [Tarantool-patches] [PATCH 7/7] fiber: refactor C backtrace and add changelog Egor Elchinov via Tarantool-patches
2021-07-01 20:24 [Tarantool-patches] [PATCH 0/7] fiber: introduce creation backtrace Egor Elchinov via Tarantool-patches
2021-07-01 20:24 ` [Tarantool-patches] [PATCH 5/7] fiber: add dynamic option for parent backtrace Egor Elchinov via Tarantool-patches
2021-07-05  9:49   ` Cyrill Gorcunov via Tarantool-patches
2021-07-09  9:50     ` Egor Elchinov via Tarantool-patches
2021-07-09 10:10       ` Cyrill Gorcunov via Tarantool-patches

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=202247f05706af029e37cff627542cc4d6dda4f7.1625153622.git.elchinov.es@gmail.com \
    --to=tarantool-patches@dev.tarantool.org \
    --cc=eelchinov@tarantool.org \
    --cc=gorcunov@tarantool.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Tarantool development patches archive

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://lists.tarantool.org/tarantool-patches/0 tarantool-patches/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 tarantool-patches tarantool-patches/ https://lists.tarantool.org/tarantool-patches \
		tarantool-patches@dev.tarantool.org.
	public-inbox-index tarantool-patches

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git