瀏覽代碼

Merge pull request #16981 from paulloz/mono-nested-exceptions

[mono] show whole trace of nested exceptions
Ignacio Etcheverry 7 年之前
父節點
當前提交
3647ebc834
共有 2 個文件被更改,包括 50 次插入23 次删除
  1. 11 3
      editor/script_editor_debugger.cpp
  2. 39 20
      modules/mono/mono_gd/gd_mono_utils.cpp

+ 11 - 3
editor/script_editor_debugger.cpp

@@ -1646,12 +1646,20 @@ void ScriptEditorDebugger::_error_selected(int p_idx) {
 		md.push_back(st[i + 1]);
 		md.push_back(st[i + 2]);
 
-		String str = func + " in " + script.get_file() + ":line " + itos(line);
+		String str = func;
+		String tooltip_str = TTR("Function:") + " " + func;
+		if (script.length() > 0) {
+			str += " in " + script.get_file();
+			tooltip_str = TTR("File:") + " " + script + "\n" + tooltip_str;
+			if (line > 0) {
+				str += ":line " + itos(line);
+				tooltip_str += "\n" + TTR("Line:") + " " + itos(line);
+			}
+		}
 
 		error_stack->add_item(str);
 		error_stack->set_item_metadata(error_stack->get_item_count() - 1, md);
-		error_stack->set_item_tooltip(error_stack->get_item_count() - 1,
-				TTR("File:") + " " + script + "\n" + TTR("Function:") + " " + func + "\n" + TTR("Line:") + " " + itos(line));
+		error_stack->set_item_tooltip(error_stack->get_item_count() - 1, tooltip_str);
 	}
 }
 

+ 39 - 20
modules/mono/mono_gd/gd_mono_utils.cpp

@@ -420,37 +420,56 @@ void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) {
 	if (!ScriptDebugger::get_singleton())
 		return;
 
-	GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace);
-	MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr());
+	ScriptLanguage::StackInfo separator;
+	separator.file = "";
+	separator.func = "--- " + TTR("End of inner exception stack trace") + " ---";
+	separator.line = 0;
 
-	MonoBoolean need_file_info = true;
-	void *ctor_args[2] = { p_exc, &need_file_info };
+	Vector<ScriptLanguage::StackInfo> si;
+	String exc_msg = "";
+
+	while (p_exc != NULL) {
+		GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace);
+		MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr());
+
+		MonoBoolean need_file_info = true;
+		void *ctor_args[2] = { p_exc, &need_file_info };
 
-	MonoObject *unexpected_exc = NULL;
-	CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc);
+		MonoObject *unexpected_exc = NULL;
+		CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc);
 
-	if (unexpected_exc != NULL) {
-		mono_print_unhandled_exception(unexpected_exc);
+		if (unexpected_exc != NULL) {
+			mono_print_unhandled_exception(unexpected_exc);
 
-		if (p_recursion_caution) {
-			// Called from CSharpLanguage::get_current_stack_info,
-			// so printing an error here could result in endless recursion
-			OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed");
-			return;
-		} else {
-			ERR_FAIL();
+			if (p_recursion_caution) {
+				// Called from CSharpLanguage::get_current_stack_info,
+				// so printing an error here could result in endless recursion
+				OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed");
+				return;
+			} else {
+				ERR_FAIL();
+			}
 		}
-	}
 
-	Vector<ScriptLanguage::StackInfo> si;
-	if (stack_trace != NULL && !p_recursion_caution)
-		si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace);
+		Vector<ScriptLanguage::StackInfo> _si;
+		if (stack_trace != NULL && !p_recursion_caution) {
+			_si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace);
+			for (int i = _si.size() - 1; i >= 0; i--)
+				si.insert(0, _si[i]);
+		}
+
+		exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc);
+
+		GDMonoProperty *p_prop = GDMono::get_singleton()->get_class(mono_object_get_class(p_exc))->get_property("InnerException");
+		p_exc = p_prop != NULL ? p_prop->get_value(p_exc) : NULL;
+		if (p_exc != NULL)
+			si.insert(0, separator);
+	}
 
 	String file = si.size() ? si[0].file : __FILE__;
 	String func = si.size() ? si[0].func : FUNCTION_STR;
 	int line = si.size() ? si[0].line : __LINE__;
 	String error_msg = "Unhandled exception";
-	String exc_msg = GDMonoUtils::get_exception_name_and_message(p_exc);
 
 	ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si);
 #endif