[Tarantool-patches] [PATCH] fiber: set diag error on madvise, mprotect fails
Alexander Turenko
alexander.turenko at tarantool.org
Wed Jan 15 16:35:49 MSK 2020
My understanding of error handling is so:
* Utility functions, simple wrappers and so just set a diag.
* A function that able to return an error to a user do it (set or pass
through a diag).
* A background / delayed function logs an occured errors.
So I think that fiber_madvise() and fiber_mprotect() should set a diag:
this is correct. Usages of those functions should do one of the
following actions:
* return -1 (the diag remains set)
* ignore the error, but log it: call diag_log() and continue
* ignore w/o even logging, but this should be commented in the code
As I see, fiber_madvise() log an occured error before the patch, now the
error is ignored. I think that doing something like the following in
fiber_stack_recycle() and fiber_stack_watermark_create() would be good:
| if (fiber_madvise(<...>) != 0)
| diag_log();
fiber_mprotect() error is handled in fiber_stack_create() (correctly
after the patch), but ignored in fiber_stack_destroy(). Let's log it in
the latter function.
This is how I understand a right way to handle exceptional situations:
don't sure it is right or very consistent with other code. So, please,
double-check my proposal.
Aside of that I googled a bit whether we can wrap madvise() / mprotect()
using LD_PRELOAD for unit testing and it seems it is doable:
https://tbrindus.ca/correct-ld-preload-hooking-libc/
I would not bother you with testing of errors in madvise() / mprotect()
right now, but it is good topic to experiment around it in a future.
See several minor comments below.
WBR, Alexander Turenko.
> Same time mprotect usage is more sensitive -- we
> setup guard pages with its help and when failing
> it is definitely an error which we should not only
> mention in logger but provide a caller diag error.
> Here is an example from memcached
Nit: I would say tarantool/memcached just to distinguish from the
original memcached software.
> issue https://github.com/tarantool/tarantool/issues/4722
> branch gorcunov/gh-4722-mprotect-diag-error
> -#define fiber_madvise(addr, len, advice) \
> -({ \
> - int err = madvise((addr), (len), (advice)); \
> - if (err) \
> - say_syserror("madvise"); \
> - err; \
> -})
> -
> -#define fiber_mprotect(addr, len, prot) \
> -({ \
> - int err = mprotect((addr), (len), (prot)); \
> - if (err) \
> - say_syserror("mprotect"); \
> - err; \
> -})
> +static inline int
> +fiber_madvise(void *addr, size_t len, int advice)
> +{
> + if (madvise(addr, len, advice)) {
Nit: We usually check against zero explicitly.
> + diag_set(SystemError, "fiber madvise %p:%zu:%d failed",
> + addr, len, advice);
> + return -1;
> + }
> + return 0;
> +}
> +
> +static inline int
> +fiber_mprotect(void *addr, size_t len, int prot)
> +{
> + if (mprotect(addr, len, prot)) {
Nit: Same here.
> + diag_set(SystemError, "fiber mprotect %p:%zu:%d failed",
> + addr, len, prot);
> + return -1;
> + }
> + return 0;
> +}
More information about the Tarantool-patches
mailing list