Merge pull request #15630 from neikeq/issue-15454
Mono: StackFrame and MonoDevelop crash fixes
This commit is contained in:
commit
d486cae701
|
@ -449,7 +449,7 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::debug_get_current_stack_info()
|
||||||
|
|
||||||
// Printing an error here will result in endless recursion, so we must be careful
|
// Printing an error here will result in endless recursion, so we must be careful
|
||||||
|
|
||||||
if (!gdmono->is_runtime_initialized() && GDMono::get_singleton()->get_api_assembly())
|
if (!gdmono->is_runtime_initialized() || !GDMono::get_singleton()->get_api_assembly() || !GDMonoUtils::mono_cache.corlib_cache_updated)
|
||||||
return Vector<StackInfo>();
|
return Vector<StackInfo>();
|
||||||
|
|
||||||
MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr());
|
MonoObject *stack_trace = mono_object_new(mono_domain_get(), CACHED_CLASS(System_Diagnostics_StackTrace)->get_mono_ptr());
|
||||||
|
@ -503,6 +503,10 @@ Vector<ScriptLanguage::StackInfo> CSharpLanguage::stack_trace_get_info(MonoObjec
|
||||||
return Vector<StackInfo>();
|
return Vector<StackInfo>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
// what if the StackFrame method is null (method_decl is empty). should we skip this frame?
|
||||||
|
// can reproduce with a MissingMethodException on internal calls
|
||||||
|
|
||||||
sif.file = GDMonoMarshal::mono_string_to_godot(file_name);
|
sif.file = GDMonoMarshal::mono_string_to_godot(file_name);
|
||||||
sif.line = file_line_num;
|
sif.line = file_line_num;
|
||||||
sif.func = GDMonoMarshal::mono_string_to_godot(method_decl);
|
sif.func = GDMonoMarshal::mono_string_to_godot(method_decl);
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
|
|
||||||
void MonoDevelopInstance::execute(const Vector<String> &p_files) {
|
void MonoDevelopInstance::execute(const Vector<String> &p_files) {
|
||||||
|
|
||||||
|
_GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN)
|
||||||
|
|
||||||
ERR_FAIL_NULL(execute_method);
|
ERR_FAIL_NULL(execute_method);
|
||||||
ERR_FAIL_COND(gc_handle.is_null());
|
ERR_FAIL_COND(gc_handle.is_null());
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,12 @@ namespace Godot
|
||||||
|
|
||||||
MethodBase methodBase = frame.GetMethod();
|
MethodBase methodBase = frame.GetMethod();
|
||||||
|
|
||||||
|
if (methodBase == null)
|
||||||
|
{
|
||||||
|
methodDecl = string.Empty;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
if (methodBase is MethodInfo methodInfo)
|
if (methodBase is MethodInfo methodInfo)
|
||||||
|
|
|
@ -44,10 +44,13 @@ namespace GDMonoUtils {
|
||||||
|
|
||||||
MonoCache mono_cache;
|
MonoCache mono_cache;
|
||||||
|
|
||||||
#define CACHE_AND_CHECK(m_var, m_val) \
|
#define CACHE_AND_CHECK(m_var, m_val) \
|
||||||
{ \
|
{ \
|
||||||
m_var = m_val; \
|
m_var = m_val; \
|
||||||
if (!m_var) ERR_PRINT("Mono Cache: Member " #m_var " is null. This is really bad!"); \
|
if (!m_var) { \
|
||||||
|
ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \
|
||||||
|
ERR_FAIL(); \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val)
|
#define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val)
|
||||||
|
@ -133,6 +136,12 @@ void MonoCache::clear_members() {
|
||||||
task_scheduler_handle = Ref<MonoGCHandle>();
|
task_scheduler_handle = Ref<MonoGCHandle>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MonoCache::cleanup() {
|
||||||
|
|
||||||
|
corlib_cache_updated = false;
|
||||||
|
godot_api_cache_updated = false;
|
||||||
|
}
|
||||||
|
|
||||||
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
|
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
|
||||||
|
|
||||||
void update_corlib_cache() {
|
void update_corlib_cache() {
|
||||||
|
@ -158,6 +167,8 @@ void update_corlib_cache() {
|
||||||
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(bool)", true));
|
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(bool)", true));
|
||||||
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true));
|
CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
mono_cache.corlib_cache_updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_godot_api_cache() {
|
void update_godot_api_cache() {
|
||||||
|
@ -231,6 +242,8 @@ void update_godot_api_cache() {
|
||||||
MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr());
|
MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr());
|
||||||
mono_runtime_object_init(task_scheduler);
|
mono_runtime_object_init(task_scheduler);
|
||||||
mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler);
|
mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler);
|
||||||
|
|
||||||
|
mono_cache.corlib_cache_updated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_cache() {
|
void clear_cache() {
|
||||||
|
@ -402,6 +415,9 @@ void print_unhandled_exception(MonoObject *p_exc) {
|
||||||
void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) {
|
void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) {
|
||||||
mono_print_unhandled_exception(p_exc);
|
mono_print_unhandled_exception(p_exc);
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
if (!ScriptDebugger::get_singleton())
|
||||||
|
return;
|
||||||
|
|
||||||
GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace);
|
GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace);
|
||||||
MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr());
|
MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr());
|
||||||
|
|
||||||
|
|
|
@ -129,10 +129,16 @@ struct MonoCache {
|
||||||
|
|
||||||
Ref<MonoGCHandle> task_scheduler_handle;
|
Ref<MonoGCHandle> task_scheduler_handle;
|
||||||
|
|
||||||
|
bool corlib_cache_updated;
|
||||||
|
bool godot_api_cache_updated;
|
||||||
|
|
||||||
void clear_members();
|
void clear_members();
|
||||||
void cleanup() {}
|
void cleanup();
|
||||||
|
|
||||||
MonoCache() {
|
MonoCache() {
|
||||||
|
corlib_cache_updated = false;
|
||||||
|
godot_api_cache_updated = false;
|
||||||
|
|
||||||
clear_members();
|
clear_members();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue