Skip to content

Commit c7de202

Browse files
authored
[mono] Fix the race condition issue of aot_module loading (#103975)
* Fix the race condition issue of aot_module loading * Clean up error after get the header * Address review feedback
1 parent b2df075 commit c7de202

File tree

5 files changed

+50
-22
lines changed

5 files changed

+50
-22
lines changed

src/mono/mono/eventpipe/ep-rt-mono-runtime-provider.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,7 @@ get_module_event_data (
815815
module_data->module_flags = MODULE_FLAGS_MANIFEST_MODULE;
816816
if (image && image->dynamic)
817817
module_data->module_flags |= MODULE_FLAGS_DYNAMIC_MODULE;
818-
if (image && image->aot_module)
818+
if (image && image->aot_module && (image->aot_module != AOT_MODULE_NOT_FOUND))
819819
module_data->module_flags |= MODULE_FLAGS_NATIVE_MODULE;
820820

821821
module_data->module_il_path = NULL;
@@ -905,7 +905,7 @@ fire_assembly_events (
905905
if (assembly->dynamic)
906906
assembly_flags |= ASSEMBLY_FLAGS_DYNAMIC_ASSEMBLY;
907907

908-
if (assembly->image && assembly->image->aot_module) {
908+
if (assembly->image && assembly->image->aot_module && (assembly->image->aot_module != AOT_MODULE_NOT_FOUND)) {
909909
assembly_flags |= ASSEMBLY_FLAGS_NATIVE_ASSEMBLY;
910910
}
911911

@@ -2152,7 +2152,7 @@ get_assembly_event_data (
21522152
if (assembly->dynamic)
21532153
assembly_data->assembly_flags |= ASSEMBLY_FLAGS_DYNAMIC_ASSEMBLY;
21542154

2155-
if (assembly->image && assembly->image->aot_module)
2155+
if (assembly->image && assembly->image->aot_module && (assembly->image->aot_module != AOT_MODULE_NOT_FOUND))
21562156
assembly_data->assembly_flags |= ASSEMBLY_FLAGS_NATIVE_ASSEMBLY;
21572157

21582158
assembly_data->assembly_name = mono_stringify_assembly_name (&assembly->aname);

src/mono/mono/mini/aot-runtime.c

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ init_amodule_got (MonoAotModule *amodule, gboolean preinit)
18281828
if (mono_defaults.corlib) {
18291829
MonoAotModule *mscorlib_amodule = mono_defaults.corlib->aot_module;
18301830

1831-
if (mscorlib_amodule)
1831+
if (mscorlib_amodule && (mscorlib_amodule != AOT_MODULE_NOT_FOUND))
18321832
amodule->shared_got [i] = mscorlib_amodule->got;
18331833
} else {
18341834
amodule->shared_got [i] = amodule->got;
@@ -2092,6 +2092,7 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer
20922092
g_free (aot_name);
20932093
}
20942094
#endif
2095+
assembly->image->aot_module = AOT_MODULE_NOT_FOUND;
20952096
return;
20962097
}
20972098
}
@@ -2143,7 +2144,7 @@ load_aot_module (MonoAssemblyLoadContext *alc, MonoAssembly *assembly, gpointer
21432144
mono_dl_close (sofile, close_error);
21442145
mono_error_cleanup (close_error);
21452146
}
2146-
assembly->image->aot_module = NULL;
2147+
assembly->image->aot_module = AOT_MODULE_NOT_FOUND;
21472148
return;
21482149
}
21492150

@@ -2525,7 +2526,7 @@ load_container_amodule (MonoAssemblyLoadContext *alc)
25252526

25262527
load_aot_module(alc, assm, NULL, error);
25272528
mono_memory_barrier ();
2528-
g_assert (assm->image->aot_module);
2529+
g_assert (assm->image->aot_module && (assm->image->aot_module != AOT_MODULE_NOT_FOUND));
25292530
container_amodule = assm->image->aot_module;
25302531
}
25312532

@@ -2599,7 +2600,7 @@ mono_aot_get_method_from_vt_slot (MonoVTable *vtable, int slot, MonoError *error
25992600

26002601
error_init (error);
26012602

2602-
if (MONO_CLASS_IS_INTERFACE_INTERNAL (klass) || m_class_get_rank (klass) || !amodule)
2603+
if (MONO_CLASS_IS_INTERFACE_INTERNAL (klass) || m_class_get_rank (klass) || !amodule || (amodule == AOT_MODULE_NOT_FOUND))
26032604
return NULL;
26042605

26052606
info = &amodule->blob [mono_aot_get_offset (amodule->class_info_offsets, mono_metadata_token_index (m_class_get_type_token (klass)) - 1)];
@@ -2635,7 +2636,7 @@ mono_aot_get_cached_class_info (MonoClass *klass, MonoCachedClassInfo *res)
26352636
guint8 *p;
26362637
gboolean err;
26372638

2638-
if (m_class_get_rank (klass) || !m_class_get_type_token (klass) || !amodule)
2639+
if (m_class_get_rank (klass) || !m_class_get_type_token (klass) || !amodule || (amodule == AOT_MODULE_NOT_FOUND))
26392640
return FALSE;
26402641

26412642
p = (guint8*)&amodule->blob [mono_aot_get_offset (amodule->class_info_offsets, mono_metadata_token_index (m_class_get_type_token (klass)) - 1)];
@@ -2675,7 +2676,7 @@ mono_aot_get_class_from_name (MonoImage *image, const char *name_space, const ch
26752676
uint32_t debug_hash;
26762677
#endif
26772678

2678-
if (!amodule || !amodule->class_name_table)
2679+
if (!amodule || (amodule == AOT_MODULE_NOT_FOUND) || !amodule->class_name_table)
26792680
return FALSE;
26802681

26812682
amodule_lock (amodule);
@@ -2784,7 +2785,7 @@ mono_aot_get_weak_field_indexes (MonoImage *image)
27842785
{
27852786
MonoAotModule *amodule = image->aot_module;
27862787

2787-
if (!amodule)
2788+
if (!amodule || (amodule == AOT_MODULE_NOT_FOUND))
27882789
return NULL;
27892790

27902791
#if ENABLE_WEAK_ATTR
@@ -3478,7 +3479,7 @@ mono_aot_get_unwind_info (MonoJitInfo *ji, guint32 *unwind_info_len)
34783479
amodule = ji->d.aot_info;
34793480
else
34803481
amodule = m_class_get_image (jinfo_get_method (ji)->klass)->aot_module;
3481-
g_assert (amodule);
3482+
g_assert (amodule && (amodule != AOT_MODULE_NOT_FOUND));
34823483
g_assert (ji->from_aot);
34833484

34843485
if (!amodule_contains_code_addr (amodule, code)) {
@@ -3615,7 +3616,7 @@ mono_aot_find_jit_info (MonoImage *image, gpointer addr)
36153616
int methods_len;
36163617
gboolean async;
36173618

3618-
if (!amodule)
3619+
if (!amodule || (amodule == AOT_MODULE_NOT_FOUND))
36193620
return NULL;
36203621

36213622
addr = MINI_FTNPTR_TO_ADDR (addr);
@@ -4510,7 +4511,7 @@ find_aot_method_in_amodule (MonoAotModule *code_amodule, MonoMethod *method, gui
45104511
// the caching breaking. The solution seems to be to cache using the "metadata" amodule.
45114512
MonoAotModule *metadata_amodule = m_class_get_image (method->klass)->aot_module;
45124513

4513-
if (!metadata_amodule || metadata_amodule->out_of_date || !code_amodule || code_amodule->out_of_date)
4514+
if (!metadata_amodule || (metadata_amodule == AOT_MODULE_NOT_FOUND) || metadata_amodule->out_of_date || !code_amodule || code_amodule->out_of_date)
45144515
return 0xffffff;
45154516

45164517
table = code_amodule->extra_method_table;
@@ -4685,7 +4686,7 @@ find_aot_method (MonoMethod *method, MonoAotModule **out_amodule)
46854686

46864687
/* Try the method's module first */
46874688
*out_amodule = m_class_get_image (method->klass)->aot_module;
4688-
index = find_aot_method_in_amodule (m_class_get_image (method->klass)->aot_module, method, hash);
4689+
index = find_aot_method_in_amodule (*out_amodule, method, hash);
46894690
if (index != 0xffffff)
46904691
return index;
46914692

@@ -4920,14 +4921,36 @@ mono_aot_get_method (MonoMethod *method, MonoError *error)
49204921
MonoClass *klass = method->klass;
49214922
MonoMethod *orig_method = method;
49224923
guint32 method_index;
4923-
MonoAotModule *amodule = m_class_get_image (klass)->aot_module;
4924+
MonoImage *image = m_class_get_image (klass);
49244925
guint8 *code = NULL;
49254926
gboolean cache_result = FALSE;
49264927
ERROR_DECL (inner_error);
49274928

49284929
error_init (error);
49294930

4930-
if (!amodule)
4931+
if (!(image->aot_module)) {
4932+
// aot_module was uninitialized
4933+
MonoMethodHeader *header = mono_method_get_header_checked (method, inner_error);
4934+
mono_error_cleanup (inner_error);
4935+
if (!header) {
4936+
return NULL;
4937+
} else if (header->code_size != 0) {
4938+
return NULL;
4939+
} else {
4940+
// IL code for the method body doesn't exist. Try waiting for aot_module to be loaded probably by another thread
4941+
int count = 0;
4942+
while (!(image->aot_module) && (count < 10)) { // The threshold of count should never be removed to prevent deadlock.
4943+
g_usleep (100);
4944+
count++;
4945+
}
4946+
if (!(image->aot_module))
4947+
return NULL;
4948+
}
4949+
}
4950+
4951+
MonoAotModule *amodule = image->aot_module;
4952+
4953+
if (amodule == AOT_MODULE_NOT_FOUND)
49314954
return NULL;
49324955

49334956
if (amodule->out_of_date)
@@ -5181,7 +5204,7 @@ mono_aot_get_method_from_token (MonoImage *image, guint32 token, MonoError *erro
51815204

51825205
error_init (error);
51835206

5184-
if (!aot_module)
5207+
if (!aot_module || aot_module == AOT_MODULE_NOT_FOUND)
51855208
return NULL;
51865209

51875210
method_index = mono_metadata_token_index (token) - 1;
@@ -5683,7 +5706,7 @@ get_mscorlib_aot_module (void)
56835706
MonoAotModule *amodule;
56845707

56855708
image = mono_defaults.corlib;
5686-
if (image && image->aot_module)
5709+
if (image && image->aot_module && (image->aot_module != AOT_MODULE_NOT_FOUND))
56875710
amodule = image->aot_module;
56885711
else
56895712
amodule = mscorlib_aot_module;
@@ -6135,7 +6158,7 @@ ui16_idx_comparer (const void *key, const void *member)
61356158
static gboolean
61366159
aot_is_slim_amodule (MonoAotModule *amodule)
61376160
{
6138-
if (!amodule)
6161+
if (!amodule || amodule == AOT_MODULE_NOT_FOUND)
61396162
return FALSE;
61406163

61416164
/* "slim" only applies to mscorlib.dll */
@@ -6173,7 +6196,7 @@ mono_aot_get_unbox_trampoline (MonoMethod *method, gpointer addr)
61736196
} else
61746197
amodule = m_class_get_image (method->klass)->aot_module;
61756198

6176-
if (amodule == NULL || method_index == 0xffffff || aot_is_slim_amodule (amodule)) {
6199+
if (!amodule || amodule == AOT_MODULE_NOT_FOUND || method_index == 0xffffff || aot_is_slim_amodule (amodule)) {
61776200
/* couldn't find unbox trampoline specifically generated for that
61786201
* method. this should only happen when an unbox trampoline is needed
61796202
* for `fullAOT code -> native-to-interp -> interp` transition if

src/mono/mono/mini/interp/transform.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,8 @@ mono_interp_jit_call_supported (MonoMethod *method, MonoMethodSignature *sig)
12211221
if (!mono_jit_call_can_be_supported_by_interp (method, sig, mono_llvm_only))
12221222
return FALSE;
12231223

1224-
if (mono_aot_only && m_class_get_image (method->klass)->aot_module && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
1224+
MonoAotModule *amodule = m_class_get_image (method->klass)->aot_module;
1225+
if (mono_aot_only && amodule && (amodule != AOT_MODULE_NOT_FOUND) && !(method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
12251226
ERROR_DECL (error);
12261227
mono_class_init_internal (method->klass);
12271228
gpointer addr = mono_aot_get_method (method, error);

src/mono/mono/mini/mini-amd64.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3125,7 +3125,8 @@ emit_call (MonoCompile *cfg, MonoCallInst *call, guint8 *code, MonoJitICallId ji
31253125

31263126
MonoMethod* const method = call->method;
31273127

3128-
if (m_class_get_image (method->klass)->aot_module)
3128+
MonoAotModule *amodule = m_class_get_image (method->klass)->aot_module;
3129+
if (amodule && (amodule != AOT_MODULE_NOT_FOUND))
31293130
/* The callee might be an AOT method */
31303131
near_call = FALSE;
31313132
if (method->dynamic)

src/mono/mono/mini/mini.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ typedef struct SeqPointInfo SeqPointInfo;
139139
//XXX this ignores if t is byref
140140
#define MONO_TYPE_IS_PRIMITIVE_SCALAR(t) ((((((t)->type >= MONO_TYPE_BOOLEAN && (t)->type <= MONO_TYPE_U8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U)))))
141141

142+
// Used by MonoImage:aot_module to indicate aot_module was not found
143+
#define AOT_MODULE_NOT_FOUND GINT_TO_POINTER (-1)
144+
142145
typedef struct
143146
{
144147
MonoClass *klass;

0 commit comments

Comments
 (0)