From e394c64d76b918f97bc2f1703670bd18a5dd334d Mon Sep 17 00:00:00 2001 From: Julien Portalier Date: Mon, 4 Feb 2019 16:33:29 +0100 Subject: [PATCH] Fix: integer overflow in main thread stack base detection Using `getrlimit` led to invalid STACK SIZE limits in some cases which in turn led to an integer overflow while detecting the stack base of the main stack. This patch replaces `getrlimit` with proper, but non portable, calls to pthread functions that return the stack of a given thread. fixes #7368 fixes #7369 --- src/fiber.cr | 21 +-------- src/lib_c/aarch64-linux-gnu/c/pthread.cr | 3 ++ src/lib_c/aarch64-linux-gnu/c/sys/resource.cr | 12 ----- src/lib_c/aarch64-linux-musl/c/pthread.cr | 3 ++ .../aarch64-linux-musl/c/sys/resource.cr | 12 ----- src/lib_c/arm-linux-gnueabihf/c/pthread.cr | 3 ++ .../arm-linux-gnueabihf/c/sys/resource.cr | 12 ----- src/lib_c/i386-linux-gnu/c/pthread.cr | 3 ++ src/lib_c/i386-linux-gnu/c/sys/resource.cr | 12 ----- src/lib_c/i386-linux-musl/c/pthread.cr | 3 ++ src/lib_c/i386-linux-musl/c/sys/resource.cr | 12 ----- src/lib_c/x86_64-darwin/c/pthread.cr | 2 + src/lib_c/x86_64-freebsd/c/pthread.cr | 4 ++ src/lib_c/x86_64-freebsd/c/sys/resource.cr | 12 ----- src/lib_c/x86_64-linux-gnu/c/pthread.cr | 3 ++ src/lib_c/x86_64-linux-gnu/c/sys/resource.cr | 12 ----- src/lib_c/x86_64-linux-musl/c/pthread.cr | 3 ++ src/lib_c/x86_64-linux-musl/c/sys/resource.cr | 12 ----- src/lib_c/x86_64-openbsd/c/pthread.cr | 2 + src/lib_c/x86_64-openbsd/c/signal.cr | 6 +++ src/lib_c/x86_64-openbsd/c/sys/resource.cr | 12 ----- src/lib_c/x86_64-openbsd/c/unistd.cr | 11 +++-- src/thread.cr | 46 ++++++++++++++++++- 23 files changed, 86 insertions(+), 135 deletions(-) delete mode 100644 src/lib_c/aarch64-linux-gnu/c/sys/resource.cr delete mode 100644 src/lib_c/aarch64-linux-musl/c/sys/resource.cr delete mode 100644 src/lib_c/arm-linux-gnueabihf/c/sys/resource.cr delete mode 100644 src/lib_c/i386-linux-gnu/c/sys/resource.cr delete mode 100644 src/lib_c/i386-linux-musl/c/sys/resource.cr delete mode 100644 src/lib_c/x86_64-freebsd/c/sys/resource.cr delete mode 100644 src/lib_c/x86_64-linux-gnu/c/sys/resource.cr delete mode 100644 src/lib_c/x86_64-linux-musl/c/sys/resource.cr delete mode 100644 src/lib_c/x86_64-openbsd/c/sys/resource.cr diff --git a/src/fiber.cr b/src/fiber.cr index a96cafb20042..bd37dc955c85 100644 --- a/src/fiber.cr +++ b/src/fiber.cr @@ -1,7 +1,4 @@ require "c/sys/mman" -{% unless flag?(:win32) %} -require "c/sys/resource" -{% end %} require "thread/linked_list" # Load the arch-specific methods to create a context and to swap from one @@ -87,28 +84,12 @@ class Fiber end # :nodoc: - def initialize + def initialize(@stack : Void*) @proc = Proc(Void).new { } @stack_top = _fiber_get_stack_top @stack_bottom = GC.stack_bottom @name = "main" - # Determine location of the top of the stack. - # The technique here works only for the main stack on a POSIX platform. - # TODO: implement for Windows with GetCurrentThreadStackLimits - # TODO: implement for pthreads using - # linux-glibc/musl: pthread_getattr_np - # macosx: pthread_get_stackaddr_np, pthread_get_stacksize_np - # freebsd: pthread_attr_get_np - # openbsd: pthread_stackseg_np - @stack = Pointer(Void).null - {% unless flag?(:win32) %} - if LibC.getrlimit(LibC::RLIMIT_STACK, out rlim) == 0 - stack_size = rlim.rlim_cur - @stack = Pointer(Void).new(@stack_bottom.address - stack_size) - end - {% end %} - @@fibers.push(self) end diff --git a/src/lib_c/aarch64-linux-gnu/c/pthread.cr b/src/lib_c/aarch64-linux-gnu/c/pthread.cr index 003ab9aa223b..3936bf128116 100644 --- a/src/lib_c/aarch64-linux-gnu/c/pthread.cr +++ b/src/lib_c/aarch64-linux-gnu/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(attr : PthreadAttrT*) : Int + fun pthread_attr_getstack(addr : PthreadAttrT*, stackaddr : Void**, stacksize : SizeT*) : Int fun pthread_condattr_destroy(attr : PthreadCondattrT*) : Int fun pthread_condattr_init(attr : PthreadCondattrT*) : Int fun pthread_condattr_setclock(attr : PthreadCondattrT*, type : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(cond : PthreadCondT*, mutex : PthreadMutexT*) : Int fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int fun pthread_detach(th : PthreadT) : Int + fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int fun pthread_equal(thread1 : PthreadT, thread2 : PthreadT) : Int fun pthread_join(th : PthreadT, thread_return : Void**) : Int fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int diff --git a/src/lib_c/aarch64-linux-gnu/c/sys/resource.cr b/src/lib_c/aarch64-linux-gnu/c/sys/resource.cr deleted file mode 100644 index bb1df9661776..000000000000 --- a/src/lib_c/aarch64-linux-gnu/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/aarch64-linux-musl/c/pthread.cr b/src/lib_c/aarch64-linux-musl/c/pthread.cr index d5da49a49319..c318bb5f4357 100644 --- a/src/lib_c/aarch64-linux-musl/c/pthread.cr +++ b/src/lib_c/aarch64-linux-musl/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(x0 : PthreadAttrT*) : Int + fun pthread_attr_getstack(x0 : PthreadAttrT*, x1 : Void**, x2 : SizeT*) : Int fun pthread_condattr_destroy(x0 : PthreadCondattrT*) : Int fun pthread_condattr_init(x0 : PthreadCondattrT*) : Int fun pthread_condattr_setclock(x0 : PthreadCondattrT*, x1 : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int fun pthread_detach(x0 : PthreadT) : Int + fun pthread_getattr_np(x0 : PthreadT, x1 : PthreadAttrT*) : Int fun pthread_join(x0 : PthreadT, x1 : Void**) : Int fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int diff --git a/src/lib_c/aarch64-linux-musl/c/sys/resource.cr b/src/lib_c/aarch64-linux-musl/c/sys/resource.cr deleted file mode 100644 index 893e06a007f1..000000000000 --- a/src/lib_c/aarch64-linux-musl/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULongLong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/arm-linux-gnueabihf/c/pthread.cr b/src/lib_c/arm-linux-gnueabihf/c/pthread.cr index 003ab9aa223b..3936bf128116 100644 --- a/src/lib_c/arm-linux-gnueabihf/c/pthread.cr +++ b/src/lib_c/arm-linux-gnueabihf/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(attr : PthreadAttrT*) : Int + fun pthread_attr_getstack(addr : PthreadAttrT*, stackaddr : Void**, stacksize : SizeT*) : Int fun pthread_condattr_destroy(attr : PthreadCondattrT*) : Int fun pthread_condattr_init(attr : PthreadCondattrT*) : Int fun pthread_condattr_setclock(attr : PthreadCondattrT*, type : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(cond : PthreadCondT*, mutex : PthreadMutexT*) : Int fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int fun pthread_detach(th : PthreadT) : Int + fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int fun pthread_equal(thread1 : PthreadT, thread2 : PthreadT) : Int fun pthread_join(th : PthreadT, thread_return : Void**) : Int fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int diff --git a/src/lib_c/arm-linux-gnueabihf/c/sys/resource.cr b/src/lib_c/arm-linux-gnueabihf/c/sys/resource.cr deleted file mode 100644 index bb1df9661776..000000000000 --- a/src/lib_c/arm-linux-gnueabihf/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/i386-linux-gnu/c/pthread.cr b/src/lib_c/i386-linux-gnu/c/pthread.cr index 944f2ce9c30b..68307de8eed1 100644 --- a/src/lib_c/i386-linux-gnu/c/pthread.cr +++ b/src/lib_c/i386-linux-gnu/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(attr : PthreadAttrT*) : Int + fun pthread_attr_getstack(addr : PthreadAttrT*, stackaddr : Void**, stacksize : SizeT*) : Int fun pthread_condattr_destroy(attr : PthreadCondattrT*) : Int fun pthread_condattr_init(attr : PthreadCondattrT*) : Int fun pthread_condattr_setclock(attr : PthreadCondattrT*, type : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(cond : PthreadCondT*, mutex : PthreadMutexT*) : Int fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int fun pthread_detach(th : PthreadT) : Int + fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int fun pthread_join(th : PthreadT, thread_return : Void**) : Int fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(attr : PthreadMutexattrT*) : Int diff --git a/src/lib_c/i386-linux-gnu/c/sys/resource.cr b/src/lib_c/i386-linux-gnu/c/sys/resource.cr deleted file mode 100644 index bb1df9661776..000000000000 --- a/src/lib_c/i386-linux-gnu/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/i386-linux-musl/c/pthread.cr b/src/lib_c/i386-linux-musl/c/pthread.cr index d5da49a49319..c318bb5f4357 100644 --- a/src/lib_c/i386-linux-musl/c/pthread.cr +++ b/src/lib_c/i386-linux-musl/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(x0 : PthreadAttrT*) : Int + fun pthread_attr_getstack(x0 : PthreadAttrT*, x1 : Void**, x2 : SizeT*) : Int fun pthread_condattr_destroy(x0 : PthreadCondattrT*) : Int fun pthread_condattr_init(x0 : PthreadCondattrT*) : Int fun pthread_condattr_setclock(x0 : PthreadCondattrT*, x1 : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int fun pthread_detach(x0 : PthreadT) : Int + fun pthread_getattr_np(x0 : PthreadT, x1 : PthreadAttrT*) : Int fun pthread_join(x0 : PthreadT, x1 : Void**) : Int fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int diff --git a/src/lib_c/i386-linux-musl/c/sys/resource.cr b/src/lib_c/i386-linux-musl/c/sys/resource.cr deleted file mode 100644 index 893e06a007f1..000000000000 --- a/src/lib_c/i386-linux-musl/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULongLong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/x86_64-darwin/c/pthread.cr b/src/lib_c/x86_64-darwin/c/pthread.cr index 5ca68fa77ce2..dd262f7d9c12 100644 --- a/src/lib_c/x86_64-darwin/c/pthread.cr +++ b/src/lib_c/x86_64-darwin/c/pthread.cr @@ -13,6 +13,8 @@ lib LibC fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int fun pthread_detach(x0 : PthreadT) : Int + fun pthread_get_stackaddr_np(x0 : PthreadT) : Void* + fun pthread_get_stacksize_np(x0 : PthreadT) : SizeT fun pthread_join(x0 : PthreadT, x1 : Void**) : Int fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int diff --git a/src/lib_c/x86_64-freebsd/c/pthread.cr b/src/lib_c/x86_64-freebsd/c/pthread.cr index 4c7a012c2424..87ae8c05c358 100644 --- a/src/lib_c/x86_64-freebsd/c/pthread.cr +++ b/src/lib_c/x86_64-freebsd/c/pthread.cr @@ -4,6 +4,10 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 1 + fun pthread_attr_destroy(x0 : PthreadAttrT*) : Int + fun pthread_attr_get_np(x0 : PthreadT, x1 : PthreadAttrT*) : Int + fun pthread_attr_getstack(x0 : PthreadAttrT*, x1 : Void**, x2 : SizeT*) : Int + fun pthread_attr_init(x0 : PthreadAttrT*) : Int fun pthread_condattr_destroy(x0 : PthreadCondattrT*) : Int fun pthread_condattr_init(x0 : PthreadCondattrT*) : Int fun pthread_condattr_setclock(x0 : PthreadCondattrT*, x1 : ClockidT) : Int diff --git a/src/lib_c/x86_64-freebsd/c/sys/resource.cr b/src/lib_c/x86_64-freebsd/c/sys/resource.cr deleted file mode 100644 index d5b2799ce2b9..000000000000 --- a/src/lib_c/x86_64-freebsd/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = Long - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/x86_64-linux-gnu/c/pthread.cr b/src/lib_c/x86_64-linux-gnu/c/pthread.cr index 944f2ce9c30b..68307de8eed1 100644 --- a/src/lib_c/x86_64-linux-gnu/c/pthread.cr +++ b/src/lib_c/x86_64-linux-gnu/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(attr : PthreadAttrT*) : Int + fun pthread_attr_getstack(addr : PthreadAttrT*, stackaddr : Void**, stacksize : SizeT*) : Int fun pthread_condattr_destroy(attr : PthreadCondattrT*) : Int fun pthread_condattr_init(attr : PthreadCondattrT*) : Int fun pthread_condattr_setclock(attr : PthreadCondattrT*, type : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(cond : PthreadCondT*, mutex : PthreadMutexT*) : Int fun pthread_create(newthread : PthreadT*, attr : PthreadAttrT*, start_routine : Void* -> Void*, arg : Void*) : Int fun pthread_detach(th : PthreadT) : Int + fun pthread_getattr_np(thread : PthreadT, attr : PthreadAttrT*) : Int fun pthread_join(th : PthreadT, thread_return : Void**) : Int fun pthread_mutexattr_destroy(attr : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(attr : PthreadMutexattrT*) : Int diff --git a/src/lib_c/x86_64-linux-gnu/c/sys/resource.cr b/src/lib_c/x86_64-linux-gnu/c/sys/resource.cr deleted file mode 100644 index bb1df9661776..000000000000 --- a/src/lib_c/x86_64-linux-gnu/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/x86_64-linux-musl/c/pthread.cr b/src/lib_c/x86_64-linux-musl/c/pthread.cr index d5da49a49319..c318bb5f4357 100644 --- a/src/lib_c/x86_64-linux-musl/c/pthread.cr +++ b/src/lib_c/x86_64-linux-musl/c/pthread.cr @@ -3,6 +3,8 @@ require "./sys/types" lib LibC PTHREAD_MUTEX_ERRORCHECK = 2 + fun pthread_attr_destroy(x0 : PthreadAttrT*) : Int + fun pthread_attr_getstack(x0 : PthreadAttrT*, x1 : Void**, x2 : SizeT*) : Int fun pthread_condattr_destroy(x0 : PthreadCondattrT*) : Int fun pthread_condattr_init(x0 : PthreadCondattrT*) : Int fun pthread_condattr_setclock(x0 : PthreadCondattrT*, x1 : ClockidT) : Int @@ -14,6 +16,7 @@ lib LibC fun pthread_cond_wait(x0 : PthreadCondT*, x1 : PthreadMutexT*) : Int fun pthread_create(x0 : PthreadT*, x1 : PthreadAttrT*, x2 : Void* -> Void*, x3 : Void*) : Int fun pthread_detach(x0 : PthreadT) : Int + fun pthread_getattr_np(x0 : PthreadT, x1 : PthreadAttrT*) : Int fun pthread_join(x0 : PthreadT, x1 : Void**) : Int fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int diff --git a/src/lib_c/x86_64-linux-musl/c/sys/resource.cr b/src/lib_c/x86_64-linux-musl/c/sys/resource.cr deleted file mode 100644 index 893e06a007f1..000000000000 --- a/src/lib_c/x86_64-linux-musl/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULongLong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/x86_64-openbsd/c/pthread.cr b/src/lib_c/x86_64-openbsd/c/pthread.cr index 018ec685694a..788823c40a31 100644 --- a/src/lib_c/x86_64-openbsd/c/pthread.cr +++ b/src/lib_c/x86_64-openbsd/c/pthread.cr @@ -20,6 +20,7 @@ lib LibC fun pthread_join(x0 : PthreadT, x1 : Void**) : Int alias PthreadKeyDestructor = (Void*) -> fun pthread_key_create(PthreadKeyT*, PthreadKeyDestructor) : Int + fun pthread_main_np : Int fun pthread_mutexattr_destroy(x0 : PthreadMutexattrT*) : Int fun pthread_mutexattr_init(x0 : PthreadMutexattrT*) : Int fun pthread_mutexattr_settype(x0 : PthreadMutexattrT*, x1 : Int) : Int @@ -30,4 +31,5 @@ lib LibC fun pthread_mutex_unlock(x0 : PthreadMutexT*) : Int fun pthread_self : PthreadT fun pthread_setspecific(PthreadKeyT, Void*) : Int + fun pthread_stackseg_np(PthreadT, StackT*) : Int end diff --git a/src/lib_c/x86_64-openbsd/c/signal.cr b/src/lib_c/x86_64-openbsd/c/signal.cr index 74af1891ee06..d28423d828a7 100644 --- a/src/lib_c/x86_64-openbsd/c/signal.cr +++ b/src/lib_c/x86_64-openbsd/c/signal.cr @@ -42,6 +42,12 @@ lib LibC SIG_DFL = SighandlerT.new(Pointer(Void).new(0_u64), Pointer(Void).null) SIG_IGN = SighandlerT.new(Pointer(Void).new(1_u64), Pointer(Void).null) + struct StackT + ss_sp : Void* + ss_size : SizeT + ss_flags : Int + end + fun kill(x0 : PidT, x1 : Int) : Int fun pthread_sigmask(Int, SigsetT*, SigsetT*) : Int fun signal(x0 : Int, x1 : Int -> Void) : Int -> Void diff --git a/src/lib_c/x86_64-openbsd/c/sys/resource.cr b/src/lib_c/x86_64-openbsd/c/sys/resource.cr deleted file mode 100644 index 893e06a007f1..000000000000 --- a/src/lib_c/x86_64-openbsd/c/sys/resource.cr +++ /dev/null @@ -1,12 +0,0 @@ -lib LibC - alias RlimT = ULongLong - - struct Rlimit - rlim_cur : RlimT - rlim_max : RlimT - end - - fun getrlimit(Int, Rlimit*) : Int - - RLIMIT_STACK = 3 -end diff --git a/src/lib_c/x86_64-openbsd/c/unistd.cr b/src/lib_c/x86_64-openbsd/c/unistd.cr index 41433e5e7f1f..58bfc271cc23 100644 --- a/src/lib_c/x86_64-openbsd/c/unistd.cr +++ b/src/lib_c/x86_64-openbsd/c/unistd.cr @@ -2,11 +2,12 @@ require "./sys/types" require "./stdint" lib LibC - F_OK = 0 - R_OK = 0x04 - W_OK = 0x02 - X_OK = 0x01 - SC_CLK_TCK = 3 + F_OK = 0 + R_OK = 0x04 + W_OK = 0x02 + X_OK = 0x01 + SC_CLK_TCK = 3 + SC_PAGESIZE = 28 fun chroot(dirname : Char*) : Int fun access(x0 : Char*, x1 : Int) : Int diff --git a/src/thread.cr b/src/thread.cr index 2fe324249879..803b2bd3b62c 100644 --- a/src/thread.cr +++ b/src/thread.cr @@ -42,7 +42,7 @@ class Thread def initialize @func = ->{} @th = LibC.pthread_self - @main_fiber = Fiber.new + @main_fiber = Fiber.new(stack_address) @@threads.push(self) end @@ -124,7 +124,7 @@ class Thread protected def start Thread.current = self - @main_fiber = fiber = Fiber.new + @main_fiber = fiber = Fiber.new(stack_address) begin @func.call @@ -135,4 +135,46 @@ class Thread Fiber.inactive(fiber) end end + + private def stack_address : Void* + address = Pointer(Void).null + + {% if flag?(:darwin) %} + # FIXME: pthread_get_stacksize_np returns bogus value on macOS X 10.9.0: + address = LibC.pthread_get_stackaddr_np(@th) - LibC.pthread_get_stacksize_np(@th) + + {% elsif flag?(:freebsd) %} + ret = LibC.pthread_attr_init(out attr) + unless ret == 0 + LibC.pthread_attr_destroy(pointerof(attr)) + raise Errno.new("pthread_attr_init", ret) + end + + if LibC.pthread_attr_get_np(@th, pointerof(attr)) == 0 + LibC.pthread_attr_getstack(pointerof(attr), pointerof(address), out _) + end + ret = LibC.pthread_attr_destroy(pointerof(attr)) + raise Errno.new("pthread_attr_destroy", ret) unless ret == 0 + + {% elsif flag?(:linux) %} + if LibC.pthread_getattr_np(@th, out attr) == 0 + LibC.pthread_attr_getstack(pointerof(attr), pointerof(address), out _) + end + ret = LibC.pthread_attr_destroy(pointerof(attr)) + raise Errno.new("pthread_attr_destroy", ret) unless ret == 0 + + {% elsif flag?(:openbsd) %} + ret = LibC.pthread_stackseg_np(@th, out stack) + raise Errno.new("pthread_stackseg_np", ret) unless ret == 0 + + address = + if LibC.pthread_main_np == 1 + stack.ss_sp - stack.ss_size + sysconf(LibC::SC_PAGESIZE) + else + stack.ss_sp - stack.ss_size + end + {% end %} + + address + end end