From 76e2ecd8ef2076d91950d720b5f2266fa087c130 Mon Sep 17 00:00:00 2001 From: Aleksey Kliger Date: Mon, 23 Aug 2021 15:36:42 -0400 Subject: [PATCH] [interp] Use existing InterpMethod if allocation and lookup race If two threads both want to get an InterpMethod for the same MonoMethod, and they both see null from the first hash table lookup, make sure that whichever one comes into the jit_mm lock second re-uses the previously inserted InterpMethod, instead of its own version. Without this change, racing threads will overwrite MonoJitInfo:seq_points (in mono_interp_transform_method) which sometimes leads to deallocating the same sequence points multiple times. Fixes https://github.com/dotnet/runtime/issues/57812 --- src/mono/mono/mini/interp/interp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6db2f621167d95..623b7afa0a86e2 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -495,8 +495,12 @@ mono_interp_get_imethod (MonoMethod *method, MonoError *error) imethod->param_types [i] = mini_get_underlying_type (sig->params [i]); jit_mm_lock (jit_mm); - if (!mono_internal_hash_table_lookup (&jit_mm->interp_code_hash, method)) + InterpMethod *old_imethod; + if (!((old_imethod = mono_internal_hash_table_lookup (&jit_mm->interp_code_hash, method)))) mono_internal_hash_table_insert (&jit_mm->interp_code_hash, method, imethod); + else { + imethod = old_imethod; /* leak the newly allocated InterpMethod to the mempool */ + } jit_mm_unlock (jit_mm); imethod->prof_flags = mono_profiler_get_call_instrumentation_flags (imethod->method);