Skip to content

Commit

Permalink
Ensure jl_get_excstack can't read from concurrently running tasks
Browse files Browse the repository at this point in the history
This might not be a major problem right now, but could become a source
of crashes once PARTR lands.
  • Loading branch information
c42f committed Feb 3, 2019
1 parent 69ac379 commit 073a7d1
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,7 @@ extern jl_sym_t *macrocall_sym; extern jl_sym_t *colon_sym;
extern jl_sym_t *hygienicscope_sym; extern jl_sym_t *escape_sym;
extern jl_sym_t *gc_preserve_begin_sym; extern jl_sym_t *gc_preserve_end_sym;
extern jl_sym_t *throw_undef_if_not_sym; extern jl_sym_t *getfield_undefref_sym;
extern jl_sym_t *failed_sym; extern jl_sym_t *done_sym; extern jl_sym_t *runnable_sym;

struct _jl_sysimg_fptrs_t;

Expand Down
12 changes: 9 additions & 3 deletions src/stackwalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,15 +181,21 @@ JL_DLLEXPORT void jl_get_backtrace(jl_array_t **btout, jl_array_t **bt2out)
// with the top of the stack and returning up to `max_entries`. If requested by
// setting the `include_bt` flag, backtrace data in bt,bt2 format is
// interleaved.
JL_DLLEXPORT jl_value_t *jl_get_excstack(jl_value_t* task, int include_bt, int max_entries)
JL_DLLEXPORT jl_value_t *jl_get_excstack(jl_task_t* task, int include_bt, int max_entries)
{
JL_TYPECHK(catch_stack, task, task);
JL_TYPECHK(catch_stack, task, (jl_value_t*)task);
jl_ptls_t ptls = jl_get_ptls_states();
if (task != ptls->current_task &&
task->state != failed_sym && task->state != done_sym) {
jl_error("Inspecting the exception stack of a task which might "
"be running concurrently isn't allowed.");
}
jl_array_t *stack = NULL;
jl_array_t *bt = NULL;
jl_array_t *bt2 = NULL;
JL_GC_PUSH3(&stack, &bt, &bt2);
stack = jl_alloc_array_1d(jl_array_any_type, 0);
jl_excstack_t *excstack = ((jl_task_t*)task)->excstack;
jl_excstack_t *excstack = task->excstack;
size_t itr = excstack ? excstack->top : 0;
int i = 0;
while (itr > 0 && i < max_entries) {
Expand Down
6 changes: 3 additions & 3 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ volatile int jl_in_stackwalk = 0;

#define ROOT_TASK_STACK_ADJUSTMENT 3000000

static jl_sym_t *done_sym;
static jl_sym_t *failed_sym;
static jl_sym_t *runnable_sym;
jl_sym_t *done_sym;
jl_sym_t *failed_sym;
jl_sym_t *runnable_sym;

extern size_t jl_page_size;
jl_datatype_t *jl_task_type;
Expand Down
4 changes: 4 additions & 0 deletions test/exceptions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ end
end == ErrorException("expected")
@test length(catch_stack(t)) == 1
@test length(catch_stack(t)[1][2]) > 0 # backtrace is nonempty
# Exception stacks should not be accessed on concurrently running tasks
t = @task ()->nothing
@test_throws ErrorException("Inspecting the exception stack of a task which might "*
"be running concurrently isn't allowed.") catch_stack(t)
end

@testset "rethrow" begin
Expand Down

0 comments on commit 073a7d1

Please sign in to comment.