On Mon, Feb 01, 2016 at 02:43:16AM +0000, Dan Good wrote: > > * add altstack_remn, returns amount of stack remaining > * increase mapping by 1 page to handle abutment case > * capture rsp earlier > * align stack to 16 bytes > > Signed-off-by: Dan Good <[email protected]>
Bit of a messy bitser, but doesn't look it will make anything worse. so go ahead and push. Unfortunately, altstack is breaking travis builds at the moment (see, e.g. https://travis-ci.org/dgibson/ccan/jobs/106661592) - but not local builds for me which is making it difficult to debug. Some investigation showed that the test prog was getting a SIGBUS, but I didn't get further than that. altstack also breaks "make all" on any non-x86_64 platform (including 32-bit x86) which is pretty horrid. For that I think we need to adjust the makefiles to look at rusty's new "ported" stuff from _info. > --- > ccan/altstack/altstack.c | 17 ++++++++++++++--- > ccan/altstack/altstack.h | 14 ++++++++++++++ > ccan/altstack/test/run.c | 20 +++++++++++++------- > 3 files changed, 41 insertions(+), 10 deletions(-) > > diff --git a/ccan/altstack/altstack.c b/ccan/altstack/altstack.c > index 6faf38f..b71c64f 100644 > --- a/ccan/altstack/altstack.c > +++ b/ccan/altstack/altstack.c > @@ -8,6 +8,7 @@ > #include <signal.h> > #include <stdio.h> > #include <string.h> > +#include <unistd.h> > #include <sys/mman.h> > > static __thread char ebuf[ALTSTACK_ERR_MAXLEN]; > @@ -37,6 +38,11 @@ static void segvjmp(int signum) > } > > static __thread void *rsp_save_[2]; > +static __thread rlim_t max_; > + > +rlim_t altstack_max(void) { > + return max_; > +} > > static ptrdiff_t rsp_save(unsigned i) { > assert(i < 2); > @@ -57,6 +63,7 @@ static __thread void *arg_, *out_; > > int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out) > { > + long pgsz = sysconf(_SC_PAGESIZE); > int ret = -1, undo = 0; > char *m; > struct rlimit rl_save; > @@ -69,11 +76,16 @@ int altstack(rlim_t max, void *(*fn)(void *), void *arg, > void **out) > fn_ = fn; > arg_ = arg; > out_ = 0; > + max_ = max; > ebuf[elen = 0] = '\0'; > if (out) *out = 0; > > + // if the first page below the mapping is in use, we get max-pgsz > usable bytes > + // add pgsz to max to guarantee at least max usable bytes > + max += pgsz; > + > ok(getrlimit(RLIMIT_STACK, &rl_save), 1); > - ok(setrlimit(RLIMIT_STACK, &(struct rlimit) { max, rl_save.rlim_max }), > 1); > + ok(setrlimit(RLIMIT_STACK, &(struct rlimit) { max_, rl_save.rlim_max > }), 1); > undo++; > > ok(m = mmap(0, max, PROT_READ|PROT_WRITE, > MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN|MAP_NORESERVE, -1, 0), 1); > @@ -91,8 +103,7 @@ int altstack(rlim_t max, void *(*fn)(void *), void *arg, > void **out) > ok(sigaction(SIGSEGV, &sa, &sa_save), 1); > undo++; > > - asm volatile ("movq %%rsp, %%r10\nmov %0, %%rsp\npush %%r10" : > : "g" (m + max) : "r10"); > - rsp_save(0); > + asm volatile ("movq %%rsp, %%r10\nmov %1, %%rsp\nmov %%rsp, > %0\nsub $8, %%rsp\npush %%r10" : "=g" (rsp_save_[0]) : "g" (m + max) : "r10"); > out_ = fn_(arg_); > asm volatile ("pop %rsp"); > ret = 0; > diff --git a/ccan/altstack/altstack.h b/ccan/altstack/altstack.h > index 5570e7b..4445a2a 100644 > --- a/ccan/altstack/altstack.h > +++ b/ccan/altstack/altstack.h > @@ -104,6 +104,20 @@ char *altstack_geterr(void); > ptrdiff_t altstack_used(void); > > /** > + * altstack_max - return usable stack size > + * > + * Returns: max value from altstack() call > + */ > +rlim_t altstack_max(void); > + > +/** > + * altstack_remn - return amount of stack remaining > + * > + * Returns: altstack_max() minus altstack_used() > + */ > +#define altstack_remn() (altstack_max() - altstack_used()) > + > +/** > * altstack_rsp_save - set initial rsp value > * > * Capture the current value of rsp for future altstack_used() > diff --git a/ccan/altstack/test/run.c b/ccan/altstack/test/run.c > index adc1020..d0b8d28 100644 > --- a/ccan/altstack/test/run.c > +++ b/ccan/altstack/test/run.c > @@ -4,6 +4,7 @@ > #include <setjmp.h> > #include <signal.h> > #include <string.h> > +#include <unistd.h> > #include <sys/mman.h> > #include <ccan/tap/tap.h> > #include <ccan/altstack/altstack.h> > @@ -20,13 +21,13 @@ enum { > }; > int fail, call1, call2; > char *m_; > -rlim_t max_; > +rlim_t msz_; > #define e(x) (900+(x)) > #define seterr(x) (errno = e(x)) > #define setcall(x) ((call1 |= !errno ? (x) : 0), (call2 |= errno || out_ ? > (x) : 0)) > #define getrlimit(...) (fail&getrlimit_ ? > (seterr(getrlimit_), -1) : (setcall(getrlimit_), > getrlimit(__VA_ARGS__))) > #define mmap(...) (fail&mmap_ ? (seterr(mmap_), > (void *)-1) : (setcall(mmap_), mmap(__VA_ARGS__))) > -#define munmap(a, b) (fail&munmap_ ? (seterr(munmap_), > -1) : (setcall(munmap_), munmap(m_=(a), max_=(b)))) > +#define munmap(a, b) (fail&munmap_ ? (seterr(munmap_), > -1) : (setcall(munmap_), munmap(m_=(a), msz_=(b)))) > #define setrlimit(...) (fail&setrlimit_ ? > (seterr(setrlimit_), -1) : (setcall(setrlimit_), > setrlimit(__VA_ARGS__))) > #define sigaltstack(...) (fail&sigaltstack_ ? > (seterr(sigaltstack_), -1) : (setcall(sigaltstack_), > sigaltstack(__VA_ARGS__))) > #define sigaction(...) (fail&sigaction_ ? > (seterr(sigaction_), -1) : (setcall(sigaction_), > sigaction(__VA_ARGS__))) > @@ -58,7 +59,9 @@ static void *wrap(void *i) > > int main(void) > { > - plan_tests(16); > + long pgsz = sysconf(_SC_PAGESIZE); > + > + plan_tests(17); > > #define chkfail(x, y, z, c1, c2) (call1 = 0, call2 = 0, errno = 0, ok1((fail > = x) && (y) && errno == (z) && call1 == (c1) && call2 == (c2))); > #define chkok( y, z, c1, c2) (call1 = 0, call2 = 0, errno = 0, fail = 0, > ok1((y) && errno == (z) && call1 == (c1) && call2 == (c2))); > @@ -86,7 +89,7 @@ int main(void) > chkfail(munmap_, altstack(8*MiB, wrap, 0, 0) == 1, e(munmap_), > getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_, > setrlimit_|sigaltstack_|sigaction_); > - if (fail = 0, munmap(m_, max_) == -1) > + if (fail = 0, munmap(m_, msz_) == -1) > err(1, "munmap"); > > chkok( altstack(1*MiB, wrap, (void *) 1000000, 0) == > -1, EOVERFLOW, > @@ -102,10 +105,12 @@ int main(void) > chkfail(munmap_, altstack(1*MiB, wrap, (void *) 1000000, 0) == > -1, EOVERFLOW, > getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_, > setrlimit_|sigaltstack_|sigaction_); > - if (fail = 0, munmap(m_, max_) == -1) > + if (fail = 0, munmap(m_, msz_) == -1) > err(1, "munmap"); > > - ok1(used > 1*MiB-1*KiB && used < 1*MiB); > + ok1(altstack_max() == 1*MiB); > + diag("used: %lu", used); > + ok1(used >= 1*MiB && used <= 1*MiB + pgsz); > > char *p; > for(p = altstack_geterr(); *p; p++) > @@ -128,7 +133,8 @@ int main(void) > getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_, > setrlimit_|munmap_|sigaltstack_|sigaction_); > > - ok1(used > 8*MiB-8*KiB && used < 8*MiB); > + diag("used: %lu", used); > + ok1(used >= 8*MiB && used <= 8*MiB + pgsz); > > used = 0; > chkok( altstack(8*MiB, wrap, (void *) 100000, 0) == 0, > 0, -- David Gibson | I'll have my music baroque, and my code david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_ | _way_ _around_! http://www.ozlabs.org/~dgibson
signature.asc
Description: PGP signature
_______________________________________________ ccan mailing list [email protected] https://lists.ozlabs.org/listinfo/ccan
