Skip to content

Commit d7f3674

Browse files
committed
Fix thread-safety violation in Allocations Profiler:
Re-use the shared `ptls->bt_data` buffer from the thread-local storage for the buffer, to ensure that each thread has a separate buffer. This buffer is shared with the exception throwing mechanism, but is safe to share since julia exception throwing never interleaves with allocations profiling.
1 parent 0bf6ce3 commit d7f3674

File tree

1 file changed

+12
-3
lines changed

1 file changed

+12
-3
lines changed

src/gc-alloc-profiler.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,25 @@ jl_combined_results g_combined_results; // Will live forever.
4747
// === stack stuff ===
4848

4949
jl_raw_backtrace_t get_raw_backtrace() JL_NOTSAFEPOINT {
50-
// A single large buffer to record backtraces onto
51-
static jl_bt_element_t static_bt_data[JL_MAX_BT_SIZE];
50+
// We first record the backtrace onto a MAX-sized buffer, so that we don't have to
51+
// allocate the buffer until we know the size. To ensure thread-safety, we *re-use the
52+
// per-thread backtrace buffer*, which is shared with Julia's exception throwing
53+
// mechanism. This sharing is safe, because this function cannot be interleaved with
54+
// exception throwing.
55+
jl_ptls_t ptls = jl_current_task->ptls;
56+
jl_bt_element_t *shared_bt_data_buffer = ptls->bt_data;
5257

53-
size_t bt_size = rec_backtrace(static_bt_data, JL_MAX_BT_SIZE, 2);
58+
size_t bt_size = rec_backtrace(shared_bt_data_buffer, JL_MAX_BT_SIZE, 2);
5459

5560
// Then we copy only the needed bytes out of the buffer into our profile.
5661
size_t bt_bytes = bt_size * sizeof(jl_bt_element_t);
5762
jl_bt_element_t *bt_data = (jl_bt_element_t*) malloc(bt_bytes);
5863
memcpy(bt_data, static_bt_data, bt_bytes);
5964

65+
// Now, "clear" the ptls buffer, so that this buffer isn't incorrectly rooting objects
66+
// in that buffer.
67+
ptls->bt_size = 0;
68+
6069
return jl_raw_backtrace_t{
6170
bt_data,
6271
bt_size

0 commit comments

Comments
 (0)