From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from [87.239.111.99] (localhost [127.0.0.1]) by dev.tarantool.org (Postfix) with ESMTP id E6E126EC41; Thu, 1 Jul 2021 23:28:15 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org E6E126EC41 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=tarantool.org; s=dev; t=1625171296; bh=USht6YfxW0gaQ37q1+C5vTYdINAJyHjYCOEASUmZHbI=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=sHeg66/wrsSBgefFMU6hU+2dGuORtbVmrtcsw5oGIGg38U4vdp90FE9XjV8VdcfZ0 tWN5OPraTjJed40Ok6E4HQVeZZBckK7fYNHb2jQePSZZaCPula+Vn2hf6GDrt2ImpZ DOq60cVKIJY2t6iGIQJpVXQJewwp+j/1FI1nle+0= Received: from smtp60.i.mail.ru (smtp60.i.mail.ru [217.69.128.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id F20676EC5B for ; Thu, 1 Jul 2021 23:25:51 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 dev.tarantool.org F20676EC5B Received: by smtp60.i.mail.ru with esmtpa (envelope-from ) id 1lz3Fu-0006gg-KU; Thu, 01 Jul 2021 23:25:51 +0300 To: gorcunov@tarantool.org, alyapunov@tarantool.org, skaplun@tarantool.org Date: Thu, 1 Jul 2021 23:24:43 +0300 Message-Id: <202247f05706af029e37cff627542cc4d6dda4f7.1625170992.git.elchinov.es@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-7564579A: B8F34718100C35BD X-77F55803: 4F1203BC0FB41BD954DFF1DC42D673FB703477AD6D36A6E3C7EF2853D6A1C7C1182A05F538085040A85D309AC295162533AC6D675F6B9E435646F6ADDF1C6879542D8DE9D60B09D6 X-7FA49CB5: FF5795518A3D127A4AD6D5ED66289B5278DA827A17800CE7D73594321916E098C2099A533E45F2D0395957E7521B51C2CFCAF695D4D8E9FCEA1F7E6F0F101C6778DA827A17800CE7A34C649281B21B01EA1F7E6F0F101C6723150C8DA25C47586E58E00D9D99D84E1BDDB23E98D2D38BD6CF32B5F8F9D4045BCE8FBC1DECCC18C899F1CF25ACDF8ACC7F00164DA146DAFE8445B8C89999728AA50765F790063783E00425F71A4181389733CBF5DBD5E9C8A9BA7A39EFB766F5D81C698A659EA7CC7F00164DA146DA9985D098DBDEAEC82FFDA4F57982C5F4F6B57BC7E6449061A352F6E88A58FB86F5D81C698A659EA73AA81AA40904B5D9A18204E546F3947C9FFED5BD9FB41755BA3038C0950A5D36C8A9BA7A39EFB766EC990983EF5C0329BA3038C0950A5D36D5E8D9A59859A8B6A5891D0E65CB7A2076E601842F6C81A1F004C906525384307823802FF610243DF43C7A68FF6260569E8FC8737B5C2249EC8D19AE6D49635B68655334FD4449CB9ECD01F8117BC8BEAAAE862A0553A39223F8577A6DFFEA7CC1948A84299AD5C643847C11F186F3C59DAA53EE0834AAEE X-B7AD71C0: AC4F5C86D027EB782CDD5689AFBDA7A24209795067102C07E8F7B195E1C978316FF1C5143AE485A77892AAF64C174D19 X-C1DE0DAB: C20DE7B7AB408E4181F030C43753B8186998911F362727C414F749A5E30D975CBCA6440478D4BA46727AA40A48F4216ED2E0BAE878D9ABF49C2B6934AE262D3EE7EAB7254005DCED7532B743992DF240BDC6A1CF3F042BAD6DF99611D93F60EFCCE3E035A672CDEE699F904B3F4130E343918A1A30D5E7FCCB5012B2E24CD356 X-C8649E89: 4E36BF7865823D7055A7F0CF078B5EC49A30900B95165D348B532EA2091F4FF6098FDCAD75C89B84CFB080A79510D341D6C77DC174F7A2DA4B3A6947B1EA15F11D7E09C32AA3244C2D7743C0C0C60D242841E64D04C271AC408A6A02710B730483B48618A63566E0 X-D57D3AED: 3ZO7eAau8CL7WIMRKs4sN3D3tLDjz0dLbV79QFUyzQ2Ujvy7cMT6pYYqY16iZVKkSc3dCLJ7zSJH7+u4VD18S7Vl4ZUrpaVfd2+vE6kuoey4m4VkSEu530nj6fImhcD4MUrOEAnl0W826KZ9Q+tr5ycPtXkTV4k65bRjmOUUP8cvGozZ33TWg5HZplvhhXbhDGzqmQDTd6OAevLeAnq3Ra9uf7zvY2zzsIhlcp/Y7m53TZgf2aB4JOg4gkr2biojbL9S8ysBdXhQbJZ+TAeEv/yIeucysHzG X-Mailru-Sender: EFA0F3A8419EF2166B053C73E674FFD5B314F339057841402E95E72E07A9297BE2527C969975515C67F54F2D6EFFC80BC77752E0C033A69E17841C44D9B5D58765F2F89A5AFDB6F16C18EFA0BB12DBB0 X-Mras: Ok Subject: [Tarantool-patches] [PATCH 5/7] fiber: add dynamic option for parent backtrace X-BeenThere: tarantool-patches@dev.tarantool.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Egor Elchinov via Tarantool-patches Reply-To: eelchinov@tarantool.org Cc: tarantool-patches@dev.tarantool.org Errors-To: tarantool-patches-bounces@dev.tarantool.org Sender: "Tarantool-patches" From: Egor Elchinov From: Egor Elchinov 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