Skip to content

Commit bd78876

Browse files
committed
Ensure jl_get_excstack can't read from concurrently running tasks
This might not be a major problem right now, but could become a source of crashes once PARTR lands.
1 parent 9f66185 commit bd78876

File tree

4 files changed

+17
-6
lines changed

4 files changed

+17
-6
lines changed

src/julia_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,7 @@ extern jl_sym_t *macrocall_sym; extern jl_sym_t *colon_sym;
10111011
extern jl_sym_t *hygienicscope_sym; extern jl_sym_t *escape_sym;
10121012
extern jl_sym_t *gc_preserve_begin_sym; extern jl_sym_t *gc_preserve_end_sym;
10131013
extern jl_sym_t *throw_undef_if_not_sym; extern jl_sym_t *getfield_undefref_sym;
1014+
extern jl_sym_t *failed_sym; extern jl_sym_t *done_sym; extern jl_sym_t *runnable_sym;
10141015

10151016
struct _jl_sysimg_fptrs_t;
10161017

src/stackwalk.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,15 +181,21 @@ JL_DLLEXPORT void jl_get_backtrace(jl_array_t **btout, jl_array_t **bt2out)
181181
// with the top of the stack and returning up to `max_entries`. If requested by
182182
// setting the `include_bt` flag, backtrace data in bt,bt2 format is
183183
// interleaved.
184-
JL_DLLEXPORT jl_value_t *jl_get_excstack(jl_value_t* task, int include_bt, int max_entries)
184+
JL_DLLEXPORT jl_value_t *jl_get_excstack(jl_task_t* task, int include_bt, int max_entries)
185185
{
186-
JL_TYPECHK(catch_stack, task, task);
186+
JL_TYPECHK(catch_stack, task, (jl_value_t*)task);
187+
jl_ptls_t ptls = jl_get_ptls_states();
188+
if (task != ptls->current_task &&
189+
task->state != failed_sym && task->state != done_sym) {
190+
jl_error("Inspecting the exception stack of a task which might "
191+
"be running concurrently isn't allowed.");
192+
}
187193
jl_array_t *stack = NULL;
188194
jl_array_t *bt = NULL;
189195
jl_array_t *bt2 = NULL;
190196
JL_GC_PUSH3(&stack, &bt, &bt2);
191197
stack = jl_alloc_array_1d(jl_array_any_type, 0);
192-
jl_excstack_t *excstack = ((jl_task_t*)task)->excstack;
198+
jl_excstack_t *excstack = task->excstack;
193199
size_t itr = excstack ? excstack->top : 0;
194200
int i = 0;
195201
while (itr > 0 && i < max_entries) {

src/task.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ volatile int jl_in_stackwalk = 0;
5959

6060
#define ROOT_TASK_STACK_ADJUSTMENT 3000000
6161

62-
static jl_sym_t *done_sym;
63-
static jl_sym_t *failed_sym;
64-
static jl_sym_t *runnable_sym;
62+
jl_sym_t *done_sym;
63+
jl_sym_t *failed_sym;
64+
jl_sym_t *runnable_sym;
6565

6666
extern size_t jl_page_size;
6767
jl_datatype_t *jl_task_type;

test/exceptions.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ end
247247
end == ErrorException("expected")
248248
@test length(catch_stack(t)) == 1
249249
@test length(catch_stack(t)[1][2]) > 0 # backtrace is nonempty
250+
# Exception stacks should not be accessed on concurrently running tasks
251+
t = @task ()->nothing
252+
@test_throws ErrorException("Inspecting the exception stack of a task which might "*
253+
"be running concurrently isn't allowed.") catch_stack(t)
250254
end
251255

252256
@testset "rethrow" begin

0 commit comments

Comments
 (0)