* [PATCH] altstack: New module
@ 2016-01-26 22:18 Dan Good
2016-01-27 4:51 ` Rusty Russell
0 siblings, 1 reply; 3+ messages in thread
From: Dan Good @ 2016-01-26 22:18 UTC (permalink / raw)
To: ccan
altstack - run a function with a dedicated stack, and then release the memory
Signed-off-by: Dan Good <dan@dancancode.com>
---
Makefile-ccan | 1 +
ccan/altstack/LICENSE | 1 +
ccan/altstack/_info | 125 ++++++++++++++++++++++++++++++++++++++++
ccan/altstack/altstack.c | 124 ++++++++++++++++++++++++++++++++++++++++
ccan/altstack/altstack.h | 114 +++++++++++++++++++++++++++++++++++++
ccan/altstack/test/run.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 509 insertions(+)
create mode 120000 ccan/altstack/LICENSE
create mode 100644 ccan/altstack/_info
create mode 100644 ccan/altstack/altstack.c
create mode 100644 ccan/altstack/altstack.h
create mode 100644 ccan/altstack/test/run.c
diff --git a/Makefile-ccan b/Makefile-ccan
index 9469334..2c80720 100644
--- a/Makefile-ccan
+++ b/Makefile-ccan
@@ -33,6 +33,7 @@ MODS_NO_SRC := alignof \
# No external dependencies, with C code:
MODS_WITH_SRC := aga \
agar \
+ altstack \
antithread \
antithread/alloc \
asort \
diff --git a/ccan/altstack/LICENSE b/ccan/altstack/LICENSE
new file mode 120000
index 0000000..4f8ee74
--- /dev/null
+++ b/ccan/altstack/LICENSE
@@ -0,0 +1 @@
+../../licenses/APACHE-2
\ No newline at end of file
diff --git a/ccan/altstack/_info b/ccan/altstack/_info
new file mode 100644
index 0000000..1b03770
--- /dev/null
+++ b/ccan/altstack/_info
@@ -0,0 +1,125 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+
+/**
+ *
+ * altstack - run a function with a dedicated stack, and then release the memory
+ *
+ * C99 introduced variable length arrays to make the language easier to use
+ * and more efficient. Many regard VLA's with distrust due to fear of stack
+ * overflow. The same fear causes many to shy away from recursion.
+ *
+ * altstack seeks to liberate us from this fear. altstack creates a dedicated stack,
+ * limited to a specified maximum size, runs a given function using this stack, and
+ * afterwards releases the memory back to the system.
+ *
+ * altstack provides a way to obtain current stack usage and a way to fail gracefully.
+ *
+ * altstack is implemented for x86-64 only.
+ *
+ * Example:
+ * // allocate a VLA on a dedicated stack and show memory usage
+ * #include <assert.h>
+ * #include <err.h>
+ * #include <stdio.h>
+ * #include <stdlib.h>
+ * #include <string.h>
+ * #include <unistd.h>
+ * #include <ccan/altstack/altstack.h>
+ *
+ * #define ok(x) ({ int __r = (x); if (__r == -1) err(1, #x); __r; })
+ *
+ * char maps[128], rss[128];
+ *
+ * static void stack_used(void) {
+ * fprintf(stderr, "stack used: %ld\n", altstack_used());
+ * }
+ *
+ * static void *fn(void *arg)
+ * {
+ * ok(system(maps));
+ *
+ * stack_used();
+ * ok(system(rss));
+ *
+ * char p[(long) arg];
+ *
+ * stack_used();
+ * ok(system(rss));
+ *
+ * memset(p, 0, sizeof(p));
+ *
+ * stack_used();
+ * ok(system(rss));
+ *
+ * return (void *) 0xaced;
+ * }
+ *
+ * int main(int argc, char *argv[])
+ * {
+ * long stk_max, vla_sz;
+ * int ret;
+ * void *out;
+ *
+ * assert(argc == 3);
+ * stk_max = strtol(argv[1], 0, 0) * 1024 * 1024;
+ * vla_sz = strtol(argv[2], 0, 0) * 1024 * 1024;
+ * assert(stk_max > 0 && vla_sz > 0);
+ *
+ * snprintf(maps, sizeof(maps), "egrep '\\[stack' /proc/%d/maps", getpid());
+ * snprintf(rss, sizeof(rss), "egrep '^VmRSS' /proc/%d/status", getpid());
+ *
+ * ok(system(maps));
+ * ok(system(rss));
+ *
+ * ret = altstack(stk_max, fn, (void *) vla_sz, &out);
+ *
+ * ok(system(maps));
+ * ok(system(rss));
+ *
+ * if (ret)
+ * altstack_perror();
+ * fprintf(stderr, "altstack return: %d, fn return: %p\n", ret, out);
+ *
+ * return 0;
+ * }
+ * // $ ./foo 1024 512
+ * // 7ffeb59a9000-7ffeb59ca000 rw-p 00000000 00:00 0 [stack]
+ * // VmRSS: 760 kB
+ * // 7f9cb6005000-7f9cf6004000 rw-p 00000000 00:00 0 [stack:25891]
+ * // stack used: 56
+ * // VmRSS: 760 kB
+ * // stack used: 536870968
+ * // VmRSS: 760 kB
+ * // stack used: 536870968
+ * // VmRSS: 525500 kB
+ * // 7ffeb59a9000-7ffeb59ca000 rw-p 00000000 00:00 0 [stack]
+ * // VmRSS: 1332 kB
+ * // altstack return: 0, fn return: 0xaced
+ * //
+ * // $ ./foo 512 1024
+ * // 7ffd62bd0000-7ffd62bf1000 rw-p 00000000 00:00 0 [stack]
+ * // VmRSS: 700 kB
+ * // 7f0d3bef6000-7f0d5bef5000 rw-p 00000000 00:00 0 [stack:25900]
+ * // stack used: 56
+ * // VmRSS: 700 kB
+ * // 7ffd62bd0000-7ffd62bf1000 rw-p 00000000 00:00 0 [stack]
+ * // VmRSS: 1336 kB
+ * // (altstack@103) SIGSEGV caught
+ * // altstack return: -1, fn return: (nil)
+ *
+ * License: APACHE-2
+ * Author: Dan Good <dan@dancancode.com>
+ */
+int main(int argc, char *argv[])
+{
+ /* Expect exactly one argument */
+ if (argc != 2)
+ return 1;
+
+ if (strcmp(argv[1], "depends") == 0)
+ return 0;
+
+ return 1;
+}
diff --git a/ccan/altstack/altstack.c b/ccan/altstack/altstack.c
new file mode 100644
index 0000000..6faf38f
--- /dev/null
+++ b/ccan/altstack/altstack.c
@@ -0,0 +1,124 @@
+/* Licensed under Apache License v2.0 - see LICENSE file for details */
+#include "config.h"
+#include "altstack.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/mman.h>
+
+static __thread char ebuf[ALTSTACK_ERR_MAXLEN];
+static __thread unsigned elen;
+
+#define bang(x) \
+ (elen += snprintf(ebuf + elen, sizeof(ebuf) - elen, \
+ "%s(altstack@%d) %s%s%s", \
+ elen ? "; " : "", __LINE__, (x), \
+ errno ? ": " : "", errno ? strerror(errno) : ""))
+
+void altstack_perror(void)
+{
+ fprintf(stderr, "%s\n", ebuf);
+}
+
+char *altstack_geterr(void)
+{
+ return ebuf;
+}
+
+static __thread jmp_buf jmp;
+
+static void segvjmp(int signum)
+{
+ longjmp(jmp, 1);
+}
+
+static __thread void *rsp_save_[2];
+
+static ptrdiff_t rsp_save(unsigned i) {
+ assert(i < 2);
+ asm volatile ("movq %%rsp, %0" : "=g" (rsp_save_[i]));
+ return (char *) rsp_save_[0] - (char *) rsp_save_[i];
+}
+
+void altstack_rsp_save(void) {
+ rsp_save(0);
+}
+
+ptrdiff_t altstack_used(void) {
+ return rsp_save(1);
+}
+
+static __thread void *(*fn_)(void *);
+static __thread void *arg_, *out_;
+
+int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out)
+{
+ int ret = -1, undo = 0;
+ char *m;
+ struct rlimit rl_save;
+ struct sigaction sa_save;
+ int errno_save;
+
+ assert(max > 0 && fn);
+ #define ok(x, y) ({ long __r = (long) (x); if (__r == -1) { bang(#x); if (y) goto out; } __r; })
+
+ fn_ = fn;
+ arg_ = arg;
+ out_ = 0;
+ ebuf[elen = 0] = '\0';
+ if (out) *out = 0;
+
+ ok(getrlimit(RLIMIT_STACK, &rl_save), 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);
+ undo++;
+
+ if (setjmp(jmp) == 0) {
+ unsigned char sigstk[MINSIGSTKSZ];
+ stack_t ss = { .ss_sp = sigstk, .ss_size = sizeof(sigstk) };
+ struct sigaction sa = { .sa_handler = segvjmp, .sa_flags = SA_NODEFER|SA_RESETHAND|SA_ONSTACK };
+
+ ok(sigaltstack(&ss, 0), 1);
+ undo++;
+
+ sigemptyset(&sa.sa_mask);
+ 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);
+ out_ = fn_(arg_);
+ asm volatile ("pop %rsp");
+ ret = 0;
+ if (out) *out = out_;
+ }
+ else {
+ errno = 0;
+ bang("SIGSEGV caught");
+ errno = EOVERFLOW;
+ }
+
+out:
+ errno_save = errno;
+
+ switch (undo) {
+ case 4:
+ ok(sigaction(SIGSEGV, &sa_save, 0), 0);
+ case 3:
+ ok(sigaltstack(&(stack_t) { .ss_flags = SS_DISABLE }, 0), 0);
+ case 2:
+ ok(munmap(m, max), 0);
+ case 1:
+ ok(setrlimit(RLIMIT_STACK, &rl_save), 0);
+ }
+
+ if (errno_save)
+ errno = errno_save;
+ return !ret && elen ? 1 : ret;
+}
diff --git a/ccan/altstack/altstack.h b/ccan/altstack/altstack.h
new file mode 100644
index 0000000..5570e7b
--- /dev/null
+++ b/ccan/altstack/altstack.h
@@ -0,0 +1,114 @@
+/* Licensed under Apache License v2.0 - see LICENSE file for details */
+#ifndef CCAN_ALTSTACK_H
+#define CCAN_ALTSTACK_H
+#include "config.h"
+
+#if ! __x86_64__
+#error "This code expects the AMD64 ABI, but __x86_64__ is false."
+#endif
+
+#include <stddef.h>
+#include <sys/resource.h>
+
+#define ALTSTACK_ERR_MAXLEN 128
+
+/**
+ * altstack - run a function with a dedicated stack, and then release the memory
+ * @max: the maximum size of the new stack
+ * @fn: a function to run
+ * @arg: an argument passed to fn
+ * @out: where to store the return of fn, optional
+ *
+ * rlimit is set to @max, and an anonymous noreserve mapping is made.
+ * A jump buffer is setup and a signal handler established for SIGSEGV.
+ * The rsp register is set to the mapped address, with the old rsp value
+ * pushed onto the new stack. The provided @fn is called, with @arg as
+ * its only argument, from non-stack addresses. Once @fn returns,
+ * rsp is popped off the stack. If @out is non-null, it gets the return
+ * value from @fn. The region is unmapped and the other changes undone.
+ *
+ * Error messages are appended to a buffer available via altstack_geterr()
+ * and altstack_perror(). errno is set by the failing call, or set to
+ * EOVERFLOW in case SIGSEGV is caught.
+ *
+ * altstack() uses thread-local storage, and should not be nested.
+ *
+ * Example:
+ * // permit recursion depth over a million
+ * // a contrived example! (-O2 replaces the recursion with a loop)
+ * #include <assert.h>
+ * #include <stdio.h>
+ * #include <stdlib.h>
+ * #include <ccan/altstack/altstack.h>
+ *
+ * unsigned depth;
+ *
+ * static void dn(unsigned long i)
+ * {
+ * depth++;
+ * if (i) dn(--i);
+ * }
+ *
+ * static void *wrap(void *i)
+ * {
+ * dn((unsigned long) i);
+ * return 0;
+ * }
+ *
+ * #define MiB (1024UL*1024UL)
+ * int main(int argc, char *argv[])
+ * {
+ * unsigned long n;
+ * assert(argc == 2);
+ * n = strtoul(argv[1], 0, 0);
+ *
+ * if (altstack(32*MiB, wrap, (void *) n, 0) != 0)
+ * altstack_perror();
+ *
+ * printf("%d\n", depth);
+ *
+ * return 0;
+ * }
+ *
+ * Returns: -1 on error; 0 on success; 1 on error after @fn returns
+ */
+int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out);
+
+/**
+ * altstack_perror - print error messages to stderr
+ */
+void altstack_perror(void);
+
+/**
+ * altstack_geterr - return the error buffer
+ *
+ * The error buffer is static thread-local storage.
+ * The buffer is reset with each altstack() call.
+ *
+ * Returns: pointer to the error buffer
+ */
+char *altstack_geterr(void);
+
+/**
+ * altstack_used - return amount of stack used
+ *
+ * This captures the current rsp value and returns
+ * the difference from the initial rsp value.
+ *
+ * Note: this can be used with any stack, including the original.
+ * When using with a non-altstack stack, call altstack_rsp_save()
+ * as early as possible to establish the initial value.
+ *
+ * Returns: difference of rsp values
+ */
+ptrdiff_t altstack_used(void);
+
+/**
+ * altstack_rsp_save - set initial rsp value
+ *
+ * Capture the current value of rsp for future altstack_used()
+ * calculations. altstack() also saves the initial rsp, so
+ * this should only be used in non-altstack contexts.
+ */
+void altstack_rsp_save(void);
+#endif
diff --git a/ccan/altstack/test/run.c b/ccan/altstack/test/run.c
new file mode 100644
index 0000000..b669175
--- /dev/null
+++ b/ccan/altstack/test/run.c
@@ -0,0 +1,144 @@
+#include <assert.h>
+#include <err.h>
+#include <errno.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <ccan/tap/tap.h>
+#include <ccan/altstack/altstack.h>
+#define _XOPEN_SOURCE 700
+#include <stdio.h>
+
+enum {
+ getrlimit_ = 1<<0,
+ setrlimit_ = 1<<1,
+ mmap_ = 1<<2,
+ sigaltstack_ = 1<<3,
+ sigaction_ = 1<<4,
+ munmap_ = 1<<5,
+};
+int fail, call1, call2;
+char *m_;
+rlim_t max_;
+#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 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__)))
+
+#define KiB (1024UL)
+#define MiB (KiB*KiB)
+#define GiB (MiB*KiB)
+#define TiB (GiB*KiB)
+
+FILE *mystderr;
+#undef stderr
+#define stderr mystderr
+#undef ok
+#include <ccan/altstack/altstack.c>
+#undef ok
+
+long used;
+
+static void __attribute__((optimize("O0"))) dn(unsigned long i)
+{
+ if (used) used = altstack_used();
+ if (i) dn(--i);
+}
+static void *wrap(void *i)
+{
+ dn((unsigned long) i);
+ return wrap;
+}
+
+int main(void)
+{
+ plan_tests(16);
+
+#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)));
+
+ chkfail(getrlimit_, altstack(8*MiB, wrap, 0, 0) == -1, e(getrlimit_),
+ 0,
+ 0);
+
+ chkfail(setrlimit_, altstack(8*MiB, wrap, 0, 0) == -1, e(setrlimit_),
+ getrlimit_,
+ 0);
+
+ chkfail(mmap_, altstack(8*MiB, wrap, 0, 0) == -1, e(mmap_),
+ getrlimit_|setrlimit_,
+ setrlimit_);
+
+ chkfail(sigaltstack_, altstack(8*MiB, wrap, 0, 0) == -1, e(sigaltstack_),
+ getrlimit_|setrlimit_|mmap_,
+ setrlimit_|munmap_);
+
+ chkfail(sigaction_, altstack(8*MiB, wrap, 0, 0) == -1, e(sigaction_),
+ getrlimit_|setrlimit_|mmap_|sigaltstack_,
+ setrlimit_|munmap_|sigaltstack_);
+
+ 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)
+ err(1, "munmap");
+
+ chkok( altstack(1*MiB, wrap, (void *) 1000000, 0) == -1, EOVERFLOW,
+ getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_,
+ setrlimit_|munmap_|sigaltstack_|sigaction_);
+
+ // be sure segv catch is repeatable (SA_NODEFER)
+ chkok( altstack(1*MiB, wrap, (void *) 1000000, 0) == -1, EOVERFLOW,
+ getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_,
+ setrlimit_|munmap_|sigaltstack_|sigaction_);
+
+ used = 1;
+ 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)
+ err(1, "munmap");
+
+ ok1(used > 1*MiB-1*KiB && used < 1*MiB);
+
+ char *p;
+ for(p = altstack_geterr(); *p; p++)
+ if (*p >= '0' && *p <= '9')
+ *p = '~';
+
+ #define estr "(altstack@~~~) SIGSEGV caught; (altstack@~~~) munmap(m, max): Unknown error ~~~"
+ ok1(strcmp(altstack_geterr(), estr) == 0);
+
+ char buf[ALTSTACK_ERR_MAXLEN*2] = {0};
+ if ((mystderr = fmemopen(buf, sizeof(buf), "w")) == NULL)
+ err(1, "fmemopen");
+
+ altstack_perror();
+ fflush(mystderr);
+ ok1(strcmp(buf, estr "\n") == 0);
+
+ used = 1;
+ chkok( altstack(8*MiB, wrap, (void *) 1000000, 0) == -1, EOVERFLOW,
+ getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_,
+ setrlimit_|munmap_|sigaltstack_|sigaction_);
+
+ ok1(used > 8*MiB-8*KiB && used < 8*MiB);
+
+ used = 0;
+ chkok( altstack(8*MiB, wrap, (void *) 100000, 0) == 0, 0,
+ getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_|munmap_,
+ setrlimit_|munmap_|sigaltstack_|sigaction_);
+
+ used = 1;
+ altstack_rsp_save();
+ dn(0);
+ ok1(used == 32);
+
+ return exit_status();
+}
--
2.4.3
_______________________________________________
ccan mailing list
ccan@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/ccan
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] altstack: New module
2016-01-26 22:18 [PATCH] altstack: New module Dan Good
@ 2016-01-27 4:51 ` Rusty Russell
[not found] ` <CACNkOJMaqTRm9wrbdV8svCzFvosi2a6QXUGJ6jJepQ5-_R-oSA@mail.gmail.com>
0 siblings, 1 reply; 3+ messages in thread
From: Rusty Russell @ 2016-01-27 4:51 UTC (permalink / raw)
To: Dan Good, ccan
Dan Good <dan@dancancode.com> writes:
> altstack - run a function with a dedicated stack, and then release the memory
>
> Signed-off-by: Dan Good <dan@dancancode.com>
Hmm, fails here:
Linux rusty-Lemur 4.2.0-23-generic #28-Ubuntu SMP Sun Dec 27 17:47:31 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
rusty@rusty-Lemur:~/devel/cvs/ccan/ccan/altstack (master)$ ccanlint -v
Module's run and api tests pass (tests_pass): FAIL
/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:1..16
ok 1 - (fail = getrlimit_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(getrlimit_))) && call1 == (0) && call2 == (0)
ok 2 - (fail = setrlimit_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(setrlimit_))) && call1 == (getrlimit_) && call2 == (0)
ok 3 - (fail = mmap_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(mmap_))) && call1 == (getrlimit_|setrlimit_) && call2 == (setrlimit_)
ok 4 - (fail = sigaltstack_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(sigaltstack_))) && call1 == (getrlimit_|setrlimit_|mmap_) && call2 == (setrlimit_|munmap_)
ok 5 - (fail = sigaction_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(sigaction_))) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_) && call2 == (setrlimit_|munmap_|sigaltstack_)
ok 6 - (fail = munmap_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == 1) && errno == ((900+(munmap_))) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_) && call2 == (setrlimit_|sigaltstack_|sigaction_)
not ok 7 - (altstack(1*((1024UL)*(1024UL)), wrap, (void *) 1000000, 0) == -1) && errno == (75) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_) && call2 == (setrlimit_|munmap_|sigaltstack_|sigaction_)
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 94)
not ok 8 - (altstack(1*((1024UL)*(1024UL)), wrap, (void *) 1000000, 0) == -1) && errno == (75) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_) && call2 == (setrlimit_|munmap_|sigaltstack_|sigaction_)
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 99)
not ok 9 - (fail = munmap_) && (altstack(1*((1024UL)*(1024UL)), wrap, (void *) 1000000, 0) == -1) && errno == (75) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_) && call2 == (setrlimit_|sigaltstack_|sigaction_)
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 104)
not ok 10 - used > 1*MiB-1*KiB && used < 1*MiB
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 108)
not ok 11 - strcmp(altstack_geterr(), estr) == 0
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 116)
not ok 12 - strcmp(buf, estr "\n") == 0
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 124)
not ok 13 - (altstack(8*((1024UL)*(1024UL)), wrap, (void *) 1000000, 0) == -1) && errno == (75) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_) && call2 == (setrlimit_|munmap_|sigaltstack_|sigaction_)
# Failed test (/home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:main() at line 129)
ok 14 - used > 8*MiB-8*KiB && used < 8*MiB
ok 15 - (altstack(8*((1024UL)*(1024UL)), wrap, (void *) 100000, 0) == 0) && errno == (0) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_|munmap_) && call2 == (setrlimit_|munmap_|sigaltstack_|sigaction_)
ok 16 - used == 32
# Looks like you failed 7 tests of 16.
Should I run the first failing test under the debugger? y
GNU gdb (Ubuntu 7.10-1ubuntu2) 7.10
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /tmp/ccanlint-12859.1804289383/run...done.
Breakpoint 1 at 0x403148: file /home/rusty/devel/cvs/ccan/ccan/tap/tap.c, line 139.
Starting program: /tmp/ccanlint-12859.1804289383/run
1..16
ok 1 - (fail = getrlimit_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(getrlimit_))) && call1 == (0) && call2 == (0)
ok 2 - (fail = setrlimit_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(setrlimit_))) && call1 == (getrlimit_) && call2 == (0)
ok 3 - (fail = mmap_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(mmap_))) && call1 == (getrlimit_|setrlimit_) && call2 == (setrlimit_)
ok 4 - (fail = sigaltstack_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(sigaltstack_))) && call1 == (getrlimit_|setrlimit_|mmap_) && call2 == (setrlimit_|munmap_)
ok 5 - (fail = sigaction_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == -1) && errno == ((900+(sigaction_))) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_) && call2 == (setrlimit_|munmap_|sigaltstack_)
ok 6 - (fail = munmap_) && (altstack(8*((1024UL)*(1024UL)), wrap, 0, 0) == 1) && errno == ((900+(munmap_))) && call1 == (getrlimit_|setrlimit_|mmap_|sigaltstack_|sigaction_) && call2 == (setrlimit_|sigaltstack_|sigaction_)
Program received signal SIGSEGV, Segmentation fault.
0x00000000004020b8 in dn (i=967233)
at /home/rusty/devel/cvs/ccan/ccan/altstack/test/run.c:51
51 if (i) dn(--i);
(gdb) p dn
$1 = {void (unsigned long)} 0x402081 <dn>
(gdb) p i
$2 = 967233
_______________________________________________
ccan mailing list
ccan@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/ccan
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] altstack: New module
[not found] ` <CACNkOJMaqTRm9wrbdV8svCzFvosi2a6QXUGJ6jJepQ5-_R-oSA@mail.gmail.com>
@ 2016-01-28 19:53 ` Rusty Russell
0 siblings, 0 replies; 3+ messages in thread
From: Rusty Russell @ 2016-01-28 19:53 UTC (permalink / raw)
To: Dan Good, ccan
Dan Good <dan@gooddan.com> writes:
> I built an ubuntu-15.10-server to see if I could replicate the issue, but
> the tests all pass. I've also run it on CentOS 7 and a current Amazon
> Linux AMI. Are you running a stock Ubuntu? Any security hardening?
No, out-of-box defaults pretty much.
Of course, it's valgrind. The following patch "fixes" it.
diff --git a/ccan/altstack/_info b/ccan/altstack/_info
index 1b03770..b411c29 100644
--- a/ccan/altstack/_info
+++ b/ccan/altstack/_info
@@ -109,6 +109,7 @@
* // (altstack@103) SIGSEGV caught
* // altstack return: -1, fn return: (nil)
*
+ * Ccanlint: tests_pass_valgrind FAIL
* License: APACHE-2
* Author: Dan Good <dan@dancancode.com>
*/
Cheers,
Rusty.
_______________________________________________
ccan mailing list
ccan@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/ccan
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-01-29 0:46 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-26 22:18 [PATCH] altstack: New module Dan Good
2016-01-27 4:51 ` Rusty Russell
[not found] ` <CACNkOJMaqTRm9wrbdV8svCzFvosi2a6QXUGJ6jJepQ5-_R-oSA@mail.gmail.com>
2016-01-28 19:53 ` Rusty Russell
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox