diff options
author | monojenkins <jo.shields+jenkins@xamarin.com> | 2020-03-26 23:38:26 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-26 23:38:26 +0300 |
commit | 0565f6e2c0e1e15f490ab0e7d4005d0e36abaa29 (patch) | |
tree | 008fda1e270c3a217cb6714f41248a6f19201ee7 | |
parent | b7196c45e8643217cffdcba5f373c7918d505973 (diff) |
Do not access unloading domains in debugger (case 1013579) (#19322)
There was a race where a domain was being unloaded while debugger would access it. A domain was only removed from the 'appdomains_list' as a very last step. The domain was already invalid to access at this point (locks freed for example).
Worse, images would be unloaded if only referenced by that domain. All places the debugger iterates domains hold the loader lock. The loader lock is acquired by the domain unloading process, so as long as a domain is not unloading when we access it inside of the loader lock we are safe.
include domain unloading check in collect_domain_bp
Co-authored-by: Jonathan Chambers <joncham@gmail.com>
-rw-r--r-- | mono/mini/debugger-agent.c | 13 | ||||
-rw-r--r-- | mono/mini/debugger-engine.c | 3 |
2 files changed, 16 insertions, 0 deletions
diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 94da5e554fd..085cf52147e 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -4337,6 +4337,9 @@ send_types_for_domain (MonoDomain *domain, void *user_data) MonoDomain* old_domain; AgentDomainInfo *info = NULL; + if (mono_domain_is_unloading (domain)) + return; + info = get_agent_domain_info (domain); g_assert (info); @@ -4357,6 +4360,9 @@ send_assemblies_for_domain (MonoDomain *domain, void *user_data) GSList *tmp; MonoDomain* old_domain; + if (mono_domain_is_unloading (domain)) + return; + old_domain = mono_domain_get (); mono_domain_set_fast (domain, TRUE); @@ -6840,6 +6846,10 @@ get_types (gpointer key, gpointer value, gpointer user_data) MonoType *t; GSList *tmp; MonoDomain *domain = (MonoDomain*)key; + + if (mono_domain_is_unloading (domain)) + return; + MonoAssemblyLoadContext *alc = mono_domain_default_alc (domain); GetTypesArgs *ud = (GetTypesArgs*)user_data; @@ -6879,6 +6889,9 @@ get_types_for_source_file (gpointer key, gpointer value, gpointer user_data) GetTypesForSourceFileArgs *ud = (GetTypesForSourceFileArgs*)user_data; MonoDomain *domain = (MonoDomain*)key; + if (mono_domain_is_unloading (domain)) + return; + AgentDomainInfo *info = (AgentDomainInfo *)domain_jit_info (domain)->agent_info; /* Update 'source_file_to_class' cache */ diff --git a/mono/mini/debugger-engine.c b/mono/mini/debugger-engine.c index 6bf2d3890c0..7f4c3a802b9 100644 --- a/mono/mini/debugger-engine.c +++ b/mono/mini/debugger-engine.c @@ -378,6 +378,9 @@ collect_domain_bp (gpointer key, gpointer value, gpointer user_data) CollectDomainData *ud = (CollectDomainData*)user_data; MonoMethod *m; + if (mono_domain_is_unloading (domain)) + return; + mono_domain_lock (domain); g_hash_table_iter_init (&iter, domain_jit_info (domain)->seq_points); while (g_hash_table_iter_next (&iter, (void**)&m, (void**)&seq_points)) { |