From 63528cca94045b9827d1fbcf3c3c8eb98044cb9f Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Sun, 1 Oct 2023 20:05:47 +0200 Subject: [PATCH] bug fixing in linux debugger --- .../IB/Debugger/Debugger.cs | 69 ++++++++++++++++--- .../IB/Debugger/DynamicTreeView.cs | 2 +- .../IB/Debugger/ExpressionEvaluation.cs | 54 ++++++++++++--- .../IB/Debugger/LocalVars.cs | 21 ++++++ .../IB/Debugger/Utility.cs | 4 ++ .../MonoDebugging/Client/ObjectValue.cs | 49 ++++++++++++- 6 files changed, 177 insertions(+), 22 deletions(-) diff --git a/VisualPascalABCNETLinux/IB/Debugger/Debugger.cs b/VisualPascalABCNETLinux/IB/Debugger/Debugger.cs index 69d061ba4..a1d8f362a 100644 --- a/VisualPascalABCNETLinux/IB/Debugger/Debugger.cs +++ b/VisualPascalABCNETLinux/IB/Debugger/Debugger.cs @@ -28,6 +28,7 @@ namespace VisualPascalABC private static Hashtable stand_types = new Hashtable(StringComparer.OrdinalIgnoreCase); private static List unit_types = new List();//spisok tipov-obertok nad moduljami private static List unit_debug_types;//to zhe samoe, no tipy Debugger.Core + private static List unit_mono_types; private static DebugType pabc_system_type = null; static AssemblyHelper() @@ -235,6 +236,17 @@ namespace VisualPascalABC } return unit_debug_types; } + + public static List GetUsesMonoTypes(Mono.Debugging.Soft.SoftDebuggerSession session) + { + if (unit_mono_types == null) + { + unit_mono_types = new List(); + foreach (var t in unit_types) + unit_mono_types.Add(session.GetType(t.FullName)); + } + return unit_mono_types; + } public static void Unload() { @@ -245,6 +257,9 @@ namespace VisualPascalABC if (unit_debug_types != null) unit_debug_types.Clear(); unit_debug_types = null; + if (unit_mono_types != null) + unit_mono_types.Clear(); + unit_mono_types = null; } } @@ -858,7 +873,14 @@ namespace VisualPascalABC } public ExpressionEvaluator evaluator; - + + public Mono.Debugging.Soft.SoftDebuggerSession DebuggerSession + { + get + { + return monoDebuggerSession; + } + } void debugProcessStarted(object sender, ProcessEventArgs e) { workbench.WidgetController.SetDebugTabsVisible(true); @@ -1530,6 +1552,8 @@ namespace VisualPascalABC if (lv.Name == "$obj$") self_lv = lv; } + if (var.ToLower() == "result" && ret_lv != null) + return new ValueItem(ret_lv); if (var.ToLower() == "self") { try @@ -1600,7 +1624,12 @@ namespace VisualPascalABC foreach (var fi in fields) { if (string.Compare(fi.Name, var, true) == 0) - return new ValueItem(fi.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions)); + { + var val = fi.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + val.parentFrame = stackFrame; + return new ValueItem(val); + } + } } @@ -1627,8 +1656,33 @@ namespace VisualPascalABC return new BaseTypeItem(tr, t); } + List types = AssemblyHelper.GetUsesMonoTypes(monoDebuggerSession); + foreach (var tm in types) + { + var tr = new Mono.Debugging.Evaluation.TypeValueReference(stackFrame.SourceBacktrace.GetEvaluationContext(stackFrame.Index, Mono.Debugging.Client.EvaluationOptions.DefaultOptions), tm); + var fields = tr.GetChildReferences(Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + foreach (var fi in fields) + { + if (string.Compare(fi.Name, var, true) == 0) + { + var val = fi.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + val.parentFrame = stackFrame; + return new ValueItem(val); + } - nvc = debuggedProcess.SelectedFunction.LocalVariables; + } + + Type unit_type = AssemblyHelper.GetType(tm.FullName); + if (unit_type != null) + { + System.Reflection.FieldInfo fi = unit_type.GetField(var, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.IgnoreCase); + if (fi != null && fi.IsLiteral) + return new ValueItem(DebugUtils.MakeMonoValue(fi.GetRawConstantValue())); + } + } + + + /*nvc = debuggedProcess.SelectedFunction.LocalVariables; List val_list = new List(); foreach (NamedValue nv in nvc)//smotrim sredi lokalnyh peremennyh { @@ -1770,15 +1824,8 @@ namespace VisualPascalABC } } - /*foreach (NamedValue nv in unit_vars) - { - IList fields = nv.Type.GetFields(BindingFlags.All); - foreach (FieldInfo fi in fields) - if (string.Compare(fi.Name, var, true) == 0) return new ValueItem(fi.GetValue(nv),fi.DeclaringType); - }*/ - if (ret_nv != null && string.Compare(var, "Result", true) == 0) - return new ValueItem(ret_nv, null); + return new ValueItem(ret_nv, null);*/ } else diff --git a/VisualPascalABCNETLinux/IB/Debugger/DynamicTreeView.cs b/VisualPascalABCNETLinux/IB/Debugger/DynamicTreeView.cs index 996eaf51f..0d7774e90 100644 --- a/VisualPascalABCNETLinux/IB/Debugger/DynamicTreeView.cs +++ b/VisualPascalABCNETLinux/IB/Debugger/DynamicTreeView.cs @@ -1791,7 +1791,7 @@ namespace VisualPascalABC set { if (value == null) - throw new ArgumentNullException("value", "Use string.Empty instead of null!"); + value = ""; if (text != value) { text = value; diff --git a/VisualPascalABCNETLinux/IB/Debugger/ExpressionEvaluation.cs b/VisualPascalABCNETLinux/IB/Debugger/ExpressionEvaluation.cs index 966247e86..388413005 100644 --- a/VisualPascalABCNETLinux/IB/Debugger/ExpressionEvaluation.cs +++ b/VisualPascalABCNETLinux/IB/Debugger/ExpressionEvaluation.cs @@ -769,7 +769,9 @@ namespace VisualPascalABC var val = tm.InvokeMethod(mi.VirtualMachine.GetThread(monoDebuggerSession.ActiveThread.Id), mi, obj != null ? this_obj : null, vals); var valref = new Mono.Debugging.Evaluation.UserVariableReference(obj.Context, ""); valref.Value = val; - return valref.CreateObjectValue(false); + var objval = valref.CreateObjectValue(false); + objval.parentFrame = stackFrame; + return objval; } private Mono.Debugging.Client.ObjectValue EvalCommonOperation(Mono.Debugging.Client.ObjectValue left, Mono.Debugging.Client.ObjectValue right, string op, string sn) @@ -5085,6 +5087,8 @@ namespace VisualPascalABC if (lv.Name == "$obj$") self_lv = lv; } + if (var.ToLower() == "result" && ret_lv != null) + return ret_lv; if (var.ToLower() == "self") { try @@ -5152,7 +5156,12 @@ namespace VisualPascalABC foreach (var fi in fields) { if (string.Compare(fi.Name, var, true) == 0) - return fi.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + { + var val = fi.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + val.parentFrame = stackFrame; + return val; + } + } @@ -5165,7 +5174,33 @@ namespace VisualPascalABC }*/ } - + List types = AssemblyHelper.GetUsesMonoTypes(monoDebuggerSession); + foreach (var tm in types) + { + var tr = new Mono.Debugging.Evaluation.TypeValueReference(stackFrame.SourceBacktrace.GetEvaluationContext(stackFrame.Index, Mono.Debugging.Client.EvaluationOptions.DefaultOptions), tm); + var fields = tr.GetChildReferences(Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + foreach (var fi in fields) + { + if (string.Compare(fi.Name, var, true) == 0) + { + Console.WriteLine("fount unit var " + var); + var val = fi.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); + val.parentFrame = stackFrame; + return val; + } + + } + + Type unit_type = AssemblyHelper.GetType(tm.FullName); + if (unit_type != null) + { + System.Reflection.FieldInfo fi = unit_type.GetField(var, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.IgnoreCase); + if (fi != null && fi.IsLiteral) + return DebugUtils.MakeMonoValue(fi.GetRawConstantValue()); + } + } + + /*List unit_vars = new List(); NamedValueCollection nvc = null; NamedValue ret_nv = null; @@ -5407,7 +5442,8 @@ namespace VisualPascalABC Type t = AssemblyHelper.GetType(_ident.name); if (t != null) { - val.type = DebugUtils.GetDebugType(t);//DebugType.Create(this.debuggedProcess.GetModule(name),(uint)t.MetadataToken); + var tm = monoDebuggerSession.GetType(t.FullName); + val.monoType = new Mono.Debugging.Evaluation.TypeValueReference(stackFrame.SourceBacktrace.GetEvaluationContext(stackFrame.Index, Mono.Debugging.Client.EvaluationOptions.DefaultOptions), tm); val.managed_type = t; } } @@ -6736,7 +6772,7 @@ namespace VisualPascalABC declaringType = tm; var vr = tr.GetChild(id.name, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); res.monoValue = vr.CreateObjectValue(false, Mono.Debugging.Client.EvaluationOptions.DefaultOptions); - + res.monoValue.parentFrame = stackFrame; } else { @@ -6792,8 +6828,8 @@ namespace VisualPascalABC public object GetSimpleValue(RetValue rv) { if (rv.prim_val != null) return rv.prim_val; - else if (rv.obj_val != null && rv.obj_val.IsPrimitive) return rv.obj_val.PrimitiveValue; - else if (rv.obj_val != null) return rv.obj_val; + else if (rv.monoValue != null && rv.monoValue.IsPrimitive) return rv.monoValue.GetRawValue(); + else if (rv.monoValue != null) return rv.monoValue; return null; } @@ -6815,9 +6851,9 @@ namespace VisualPascalABC args.Add(GetSimpleValue(rv)); } res.prim_val = EvalStandFuncWithParam(id.name, args.ToArray()); - if (res.prim_val is Value) + if (res.prim_val is Mono.Debugging.Client.ObjectValue) { - res.obj_val = res.prim_val as Value; + res.monoValue = res.prim_val as Mono.Debugging.Client.ObjectValue; res.prim_val = null; } } diff --git a/VisualPascalABCNETLinux/IB/Debugger/LocalVars.cs b/VisualPascalABCNETLinux/IB/Debugger/LocalVars.cs index 49016662e..1f044b4d1 100644 --- a/VisualPascalABCNETLinux/IB/Debugger/LocalVars.cs +++ b/VisualPascalABCNETLinux/IB/Debugger/LocalVars.cs @@ -584,6 +584,8 @@ namespace VisualPascalABC { if (monoValue.Name.IndexOf(':') != -1) return monoValue.Name.Substring(0, monoValue.Name.IndexOf(':')); + if (monoValue.Name.StartsWith("$rv_")) + return "Result"; return monoValue.Name; } catch @@ -801,7 +803,26 @@ namespace VisualPascalABC if (monoValue.IsObject) { if (monoValue.TypeName.IndexOf("System.Collections.Generic.") != -1) + { + var tm = monoValue.Type as Mono.Debugger.Soft.TypeMirror; + var fields = tm.GetFields(); + foreach (var fi in fields) + { + try + { + var valref = new Mono.Debugging.Evaluation.UserVariableReference(monoValue.Context, fi.Name); + valref.Value = tm.GetValue(fi, fi.VirtualMachine.GetThread(VisualPascalABC.WorkbenchServiceFactory.DebuggerManager.DebuggerSession.ActiveThread.Id)); + + list.Add(new ValueItem(valref.CreateObjectValue(false))); + } + catch (System.Exception ex) + { + Console.WriteLine(ex.Message); + } + + } return list; + } foreach (var element in monoValue.GetAllChildren()) { diff --git a/VisualPascalABCNETLinux/IB/Debugger/Utility.cs b/VisualPascalABCNETLinux/IB/Debugger/Utility.cs index 951212d8e..025c63c33 100644 --- a/VisualPascalABCNETLinux/IB/Debugger/Utility.cs +++ b/VisualPascalABCNETLinux/IB/Debugger/Utility.cs @@ -253,6 +253,10 @@ namespace VisualPascalABC public static Mono.Debugging.Client.ObjectValue MakeMonoValue(object obj) { + if (obj is Mono.Debugging.Client.ObjectValue) + return obj as Mono.Debugging.Client.ObjectValue; + if (obj is string) + return Mono.Debugging.Client.ObjectValue.CreateString(null, new Mono.Debugging.Client.ObjectPath(""), obj.GetType().Name, obj as string); return Mono.Debugging.Client.ObjectValue.CreatePrimitive(null, new Mono.Debugging.Client.ObjectPath(""), obj.GetType().Name, new Mono.Debugging.Backend.EvaluationResult(obj.ToString()), Mono.Debugging.Client.ObjectValueFlags.Literal, obj); } diff --git a/VisualPascalABCNETLinux/MonoDebugging/Client/ObjectValue.cs b/VisualPascalABCNETLinux/MonoDebugging/Client/ObjectValue.cs index 1b5b188e6..2fd53b65e 100644 --- a/VisualPascalABCNETLinux/MonoDebugging/Client/ObjectValue.cs +++ b/VisualPascalABCNETLinux/MonoDebugging/Client/ObjectValue.cs @@ -127,7 +127,14 @@ namespace Mono.Debugging.Client val.path = path; return val; } - + + public static ObjectValue CreateString(IObjectValueSource source, ObjectPath path, string typeName, string value) + { + var obj = CreateObject(source, path, typeName, new EvaluationResult(value), ObjectValueFlags.Object, new ObjectValue[0]); + obj.rawValue = value; + return obj; + } + public static ObjectValue CreateObject (IObjectValueSource source, ObjectPath path, string typeName, string value, ObjectValueFlags flags, ObjectValue[] children) { return CreateObject (source, path, typeName, new EvaluationResult (value), flags, children); @@ -139,6 +146,46 @@ namespace Mono.Debugging.Client val.flags = flags | ObjectValueFlags.Object; val.displayValue = value.DisplayValue; val.value = value.Value; + if (val.value != null && val.value.IndexOf("[") != -1 && val.typeName != null && val.typeName.IndexOf("array of") != -1) + { + string t = val.value.Substring(0, val.value.IndexOf("[")); + StringBuilder sb = new StringBuilder(); + StringBuilder buf = new StringBuilder(); + int i = 0; + while (i < t.Length) + { + char c = t[i]; + if (char.IsLetterOrDigit(c)) + buf.Append(c); + else if (c != ']') + { + string tt = buf.ToString(); + string pascalType = ""; + if (c == '*') + sb.Append("^"); + else if (c == '[') + sb.Append("array of "); + if (pascalTypes.TryGetValue(tt, out pascalType)) + sb.Append(pascalType); + else + sb.Append(tt); + if (c != '*' && c != ']' && c != '[') + sb.Append(c); + buf.Clear(); + } + i++; + } + if (buf.Length > 0) + { + string tt = buf.ToString(); + string pascalType = ""; + if (pascalTypes.TryGetValue(tt, out pascalType)) + sb.Append(pascalType); + else + sb.Append(type); + } + val.value = sb.ToString() + val.value.Substring(val.value.IndexOf("[")); + } val.type = type; val.ctx = ctx; if (children != null) {