summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2020-03-28 22:39:01 +1100
committerDamien George <damien.p.george@gmail.com>2020-03-31 09:35:46 +1100
commit8fff0b0acd96c22a555665467d3cf0d87af917e9 (patch)
tree9f85adaa95e2b6fae291e8287e6d756b1bfd10b1
parent581f9135a4148e236d62b2d28911f98aa92905e1 (diff)
unix/mpthreadport: Ensure enough thread stack to detect overflow.
Following up to 5e6cee07aba4fd73c13024f091a287171bea1f17, some systems (eg FreeBSD 12.0 64-bit) will crash if the stack-overflow margin is too small. It seems the margin of 8192 bytes (or thereabouts) is always needed. This commit adds this much margin if the requested stack size is too small. Fixes issue #5824.
-rw-r--r--ports/unix/mpthreadport.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c
index 330cc1341..c79521466 100644
--- a/ports/unix/mpthreadport.c
+++ b/ports/unix/mpthreadport.c
@@ -47,6 +47,9 @@
#define MP_THREAD_GC_SIGNAL (SIGUSR1)
#endif
+// This value seems to be about right for both 32-bit and 64-bit builds.
+#define THREAD_STACK_OVERFLOW_MARGIN (8192)
+
// this structure forms a linked list, one node per active thread
typedef struct _thread_t {
pthread_t id; // system id of thread
@@ -193,6 +196,11 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
*stack_size = PTHREAD_STACK_MIN;
}
+ // ensure there is enough stack to include a stack-overflow margin
+ if (*stack_size < 2 * THREAD_STACK_OVERFLOW_MARGIN) {
+ *stack_size = 2 * THREAD_STACK_OVERFLOW_MARGIN;
+ }
+
// set thread attributes
pthread_attr_t attr;
int ret = pthread_attr_init(&attr);
@@ -220,12 +228,7 @@ void mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) {
}
// adjust stack_size to provide room to recover from hitting the limit
- // this value seems to be about right for both 32-bit and 64-bit builds
- if (*stack_size >= 2 * 8192) {
- *stack_size -= 8192;
- } else {
- *stack_size /= 2;
- }
+ *stack_size -= THREAD_STACK_OVERFLOW_MARGIN;
// add thread to linked list of all threads
thread_t *th = malloc(sizeof(thread_t));