Skip to content

Commit

Permalink
avoid running finish_task inside of throw_internal
Browse files Browse the repository at this point in the history
if throw_internal is running from the segv_handler, there might not be enough stack to run arbitrary functions
this change, therefore, makes stack overflow in tasks more reliable

(cherry picked from commit ca9d5e7)
ref #13963
  • Loading branch information
vtjnash authored and tkelman committed Nov 29, 2015
1 parent cb2aa46 commit bb90989
Showing 1 changed file with 22 additions and 14 deletions.
36 changes: 22 additions & 14 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,12 +232,26 @@ static void throw_if_exception_set(jl_task_t *t)
}
}

static void NOINLINE NORETURN start_task()
static void record_backtrace(void);
static void NOINLINE NORETURN start_task(void)
{
// this runs the first time we switch to a task
jl_task_t *t = jl_current_task;
throw_if_exception_set(t);
jl_value_t *res = jl_apply(t->start, NULL, 0);
jl_value_t *res;
if (t->exception != NULL && t->exception != jl_nothing) {
record_backtrace();
res = t->exception;
}
else {
JL_TRY {
res = jl_apply(t->start, NULL, 0);
}
JL_CATCH {
res = jl_exception_in_transit;
t->exception = res;
jl_gc_wb(t, res);
}
}
finish_task(t, res);
abort();
}
Expand Down Expand Up @@ -795,17 +809,11 @@ void NORETURN throw_internal(jl_value_t *e)
jl_longjmp(jl_current_task->eh->eh_ctx, 1);
}
else {
if (jl_current_task == jl_root_task) {
jl_printf(JL_STDERR, "fatal: error thrown and no exception handler available.\n");
jl_static_show(JL_STDERR, e);
jl_printf(JL_STDERR, "\n");
jlbacktrace();
jl_exit(1);
}
jl_current_task->exception = e;
jl_gc_wb(jl_current_task, e);
finish_task(jl_current_task, e);
assert(0);
jl_printf(JL_STDERR, "fatal: error thrown and no exception handler available.\n");
jl_static_show(JL_STDERR, e);
jl_printf(JL_STDERR, "\n");
jlbacktrace();
jl_exit(1);
}
assert(0);
}
Expand Down

0 comments on commit bb90989

Please sign in to comment.