From: Alexander Turenko <alexander.turenko@tarantool.org> To: Cyrill Gorcunov <gorcunov@gmail.com> Cc: tml <tarantool-patches@dev.tarantool.org> Subject: Re: [Tarantool-patches] [PATCH v2 1/2] fiber: use diag_ logger in fiber_madvise/mprotect failures Date: Tue, 4 Feb 2020 00:56:27 +0300 [thread overview] Message-ID: <20200203215627.l55b6rikwubeaqvn@tkn_work_nb> (raw) In-Reply-To: <20200115170524.20471-2-gorcunov@gmail.com> Everything looks correct. However, I don't believe my eyes, so I wrote a test case (see below). Don't sure whether it is good to have error injections for such functions. Maybe LD_PRELOAD way is better (see [1]). Anyway, I checked that the behaviour was incorrect using the test and that it becomes correct. Please, consider the shared test and decide whether it worth to add it to the repository (I don't sure). [1]: https://tbrindus.ca/correct-ld-preload-hooking-libc/ WBR, Alexander Turenko. On Wed, Jan 15, 2020 at 08:05:23PM +0300, Cyrill Gorcunov wrote: > Both madvise and mprotect calls can fail due to various > reasons, mostly because of lack of free memory in the > system. > > We log such cases via say_x helpers but this is not enough. > In particular tarantool/memcached relies on diag error to be > set to detect an error condition: > > | expire_fiber = fiber_new(name, memcached_expire_loop); > | const box_error_t *err = box_error_last(); > | if (err) { > | say_error("Can't start the expire fiber"); > | say_error("%s", box_error_message(err)); > | return -1; > | } > > Thus lets use diag_set() helper here and instead of macros > use inline functions for better readability. > > Fixes #4722 > > Reported-by: Alexander Turenko <alexander.turenko@tarantool.org> > Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com> > --- > src/lib/core/fiber.c | 70 +++++++++++++++++++++++++++++++++----------- > 1 file changed, 53 insertions(+), 17 deletions(-) ---- diff --git a/src/lib/core/errinj.h b/src/lib/core/errinj.h index 672da2119..10d761e69 100644 --- a/src/lib/core/errinj.h +++ b/src/lib/core/errinj.h @@ -135,6 +135,9 @@ struct errinj { _(ERRINJ_COIO_SENDFILE_CHUNK, ERRINJ_INT, {.iparam = -1}) \ _(ERRINJ_SWIM_FD_ONLY, ERRINJ_BOOL, {.bparam = false}) \ _(ERRINJ_DYN_MODULE_COUNT, ERRINJ_INT, {.iparam = 0}) \ + _(ERRINJ_FIBER_MADVISE, ERRINJ_BOOL, {.bparam = false}) \ + _(ERRINJ_FIBER_MPROTECT_PROT_NONE, ERRINJ_BOOL, {.bparam = false}) \ + ENUM0(errinj_id, ERRINJ_LIST); extern struct errinj errinjs[]; diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c index fdad7607c..b698419cf 100644 --- a/src/lib/core/fiber.c +++ b/src/lib/core/fiber.c @@ -41,6 +41,7 @@ #include "assoc.h" #include "memory.h" #include "trigger.h" +#include "errinj.h" #if ENABLE_FIBER_TOP #include <x86intrin.h> /* __rdtscp() */ @@ -176,7 +177,12 @@ static int (*fiber_invoke)(fiber_func f, va_list ap); static inline int fiber_madvise(void *addr, size_t len, int advice) { - if (madvise(addr, len, advice) != 0) { + int rc = 0; + ERROR_INJECT(ERRINJ_FIBER_MADVISE, { + errno = ENOMEM; + rc = -1; + }); + if (rc != 0 || madvise(addr, len, advice) != 0) { diag_set(SystemError, "fiber madvise %p:%zu:%d failed", addr, len, advice); return -1; @@ -187,7 +193,14 @@ fiber_madvise(void *addr, size_t len, int advice) static inline int fiber_mprotect(void *addr, size_t len, int prot) { - if (mprotect(addr, len, prot) != 0) { + int rc = 0; + ERROR_INJECT(ERRINJ_FIBER_MPROTECT_PROT_NONE, { + if (prot == PROT_NONE) { + errno = ENOMEM; + rc = -1; + } + }); + if (rc != 0 || mprotect(addr, len, prot) != 0) { diag_set(SystemError, "fiber mprotect %p:%zu:%d failed", addr, len, prot); return -1; diff --git a/test/unit/fiber.cc b/test/unit/fiber.cc index 91f7d43f9..d64c4f89d 100644 --- a/test/unit/fiber.cc +++ b/test/unit/fiber.cc @@ -2,6 +2,7 @@ #include "fiber.h" #include "unit.h" #include "trivia/util.h" +#include "errinj.h" static struct fiber_attr default_attr; @@ -181,12 +182,43 @@ fiber_name_test() footer(); } +static void +fiber_mprotect_fail_test(void) +{ + header(); + + /* + * Set non-default stack size to prevent reusing of an + * existing fiber. + */ + struct fiber_attr *fiber_attr = fiber_attr_new(); + fiber_attr_setstacksize(fiber_attr, default_attr.stack_size * 2); + + /* + * Clear the fiber's diagnostics area to check that failed + * fiber_new() sets an error. + */ + diag_clear(diag_get()); + + struct errinj *errinj = &errinjs[ERRINJ_FIBER_MPROTECT_PROT_NONE]; + errinj->bparam = true; + struct fiber *fiber = fiber_new_ex("test_mprotect", fiber_attr, noop_f); + errinj->bparam = false; + + ok(fiber == NULL, "failed mprotect() causes fiber_new() fail"); + struct error *error = diag_last_error(diag_get()); + ok(error != NULL, "failed fiber_new() sets an error"); + + footer(); +} + static int main_f(va_list ap) { fiber_name_test(); fiber_join_test(); fiber_stack_test(); + fiber_mprotect_fail_test(); ev_break(loop(), EVBREAK_ALL); return 0; }
next prev parent reply other threads:[~2020-02-03 21:56 UTC|newest] Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-01-15 17:05 [Tarantool-patches] [PATCH v2 0/2] fiber: Handle stack madvise/mprotect errors Cyrill Gorcunov 2020-01-15 17:05 ` [Tarantool-patches] [PATCH v2 1/2] fiber: use diag_ logger in fiber_madvise/mprotect failures Cyrill Gorcunov 2020-02-03 21:56 ` Alexander Turenko [this message] 2020-02-03 22:05 ` Cyrill Gorcunov 2020-02-03 22:10 ` Alexander Turenko 2020-01-15 17:05 ` [Tarantool-patches] [PATCH v2 2/2] fiber: exit with panic if we unable to revert guard page Cyrill Gorcunov 2020-02-03 22:03 ` Alexander Turenko 2020-02-04 15:47 ` Konstantin Osipov 2020-02-04 16:08 ` Cyrill Gorcunov
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=20200203215627.l55b6rikwubeaqvn@tkn_work_nb \ --to=alexander.turenko@tarantool.org \ --cc=gorcunov@gmail.com \ --cc=tarantool-patches@dev.tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v2 1/2] fiber: use diag_ logger in fiber_madvise/mprotect failures' \ /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
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox