From b1dd19e685ba9f658d84be03a06ac365ff92730c Mon Sep 17 00:00:00 2001 From: Jonathan CHang Date: Mon, 18 Jul 2022 11:13:19 -0500 Subject: Provide listed assembly for debugger session --- Mono.Debugging.Soft/SoftDebuggerSession.cs | 45 ++++++++++-- Mono.Debugging/Mono.Debugging.Client/Assembly.cs | 79 ++++++++++++++++++++++ .../Mono.Debugging.Client/AssemblyEventArgs.cs | 11 +++ .../Mono.Debugging.Client/DebuggerSession.cs | 36 +++++++++- .../Mono.Debugging.Client/ProcessInfo.cs | 8 +++ 5 files changed, 173 insertions(+), 6 deletions(-) create mode 100644 Mono.Debugging/Mono.Debugging.Client/Assembly.cs diff --git a/Mono.Debugging.Soft/SoftDebuggerSession.cs b/Mono.Debugging.Soft/SoftDebuggerSession.cs index ecd28ca..5661168 100644 --- a/Mono.Debugging.Soft/SoftDebuggerSession.cs +++ b/Mono.Debugging.Soft/SoftDebuggerSession.cs @@ -49,7 +49,8 @@ using Mono.Debugging.Evaluation; using StackFrame = Mono.Debugger.Soft.StackFrame; using System.Collections.Immutable; - +using Assembly = Mono.Debugging.Client.Assembly; + namespace Mono.Debugging.Soft { public class SoftDebuggerSession : DebuggerSession @@ -2248,9 +2249,8 @@ namespace Mono.Debugging.Soft if (events.Length > 1 && events.Any (a => a.Assembly != asm)) throw new InvalidOperationException ("Simultaneous AssemblyLoadEvent for multiple assemblies"); - OnAssemblyLoaded(asm.Location); - - RegisterAssembly(asm); + HandleAssemblyLoaded (asm); + RegisterAssembly (asm); bool isExternal; isExternal = !UpdateAssemblyFilters (asm) && userAssemblyNames != null; @@ -2260,6 +2260,43 @@ namespace Mono.Debugging.Soft } } + private void HandleAssemblyLoaded (AssemblyMirror asm) + { + var symbolStatus = string.Empty; + var assemblyName = string.Empty; + var hasSymbol = false; + var name = asm.GetName (); + var assemblyObject = asm.GetAssemblyObject (); + if (!asm.IsDynamic) { + var metaData = asm.GetMetadata (); + symbolStatus = metaData.MainModule.HasSymbols == true ? "Symbol loaded" : "Skipped loading symbols"; + assemblyName = metaData.MainModule.Name; + hasSymbol = metaData.MainModule.HasSymbols; + } else { + symbolStatus = "Skipped loading symbol (dynamic)"; + assemblyName = "Dynamic assembly"; + hasSymbol = false; + } + var assembly = new Assembly ( + assemblyName, + asm.Location, + true, + hasSymbol, + symbolStatus, + "", + -1, + name.Version.Major.ToString (), + // TODO: module time stamp + "", + assemblyObject.Address.ToString (), + string.Format ("[{0}]{1}", asm.VirtualMachine.TargetProcess.Id, asm.VirtualMachine.TargetProcess.ProcessName), + asm.Domain.FriendlyName, + asm.VirtualMachine.TargetProcess.Id + ); + + OnAssemblyLoaded (assembly); + } + void RegisterAssembly (AssemblyMirror asm) { var domain = vm.Version.AtLeast (2, 45) ? asm.Domain : asm.GetAssemblyObject ().Domain; diff --git a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs new file mode 100644 index 0000000..4a9ad60 --- /dev/null +++ b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs @@ -0,0 +1,79 @@ +// +// Assembly.cs +// +// Author: +// Jonathan Chang +// +// Copyright (c) 2022 +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +using System; +namespace Mono.Debugging.Client +{ + public class Assembly + { + public Assembly (string name, string path, bool optimized, bool userCode, string symbolStatus, string symbolFile, int? order, string version, string timestamp, string address, string process, string appdomain, long? processId) + { + Name = name; + Path = path; + Optimized = optimized; + SymbolStatus = symbolStatus; + SymbolFile = symbolFile; + Order = order.GetValueOrDefault (-1); + TimeStamp = timestamp; + Address = address; + Process = process; + AppDomain = appdomain; + Version = version; + UserCode = userCode; + ProcessId = processId; + + } + public Assembly (string path) + { + Path = path; + } + + public string Name { get; private set; } + + public string Path { get; private set; } + + public bool Optimized { get; private set; } + + public bool UserCode { get; private set; } + + public string SymbolStatus { get; private set; } + + public string SymbolFile { get; private set; } + + public int Order { get; private set; } = -1; + + public string Version { get; private set; } + + public string TimeStamp { get; private set; } + + public string Address { get; private set; } + + public string Process { get; private set; } + + public string AppDomain { get; private set; } + + public long? ProcessId { get; private set; } = -1; + } +} \ No newline at end of file diff --git a/Mono.Debugging/Mono.Debugging.Client/AssemblyEventArgs.cs b/Mono.Debugging/Mono.Debugging.Client/AssemblyEventArgs.cs index 7d119f2..c97f79c 100644 --- a/Mono.Debugging/Mono.Debugging.Client/AssemblyEventArgs.cs +++ b/Mono.Debugging/Mono.Debugging.Client/AssemblyEventArgs.cs @@ -30,13 +30,24 @@ namespace Mono.Debugging.Client { public class AssemblyEventArgs : EventArgs { + public AssemblyEventArgs (Assembly assembly) + { + Location = assembly.Path; + Assembly = assembly; + } + public AssemblyEventArgs (string location) { Location = location; + Assembly = new Assembly (location); } public string Location { get; private set; } + + public Assembly Assembly { + get; private set; + } } } diff --git a/Mono.Debugging/Mono.Debugging.Client/DebuggerSession.cs b/Mono.Debugging/Mono.Debugging.Client/DebuggerSession.cs index c6a0fee..32ca3ff 100644 --- a/Mono.Debugging/Mono.Debugging.Client/DebuggerSession.cs +++ b/Mono.Debugging/Mono.Debugging.Client/DebuggerSession.cs @@ -32,6 +32,7 @@ using System.Collections.Generic; using Mono.Debugging.Backend; using Mono.Debugging.Evaluation; +using System.Linq; namespace Mono.Debugging.Client { @@ -49,6 +50,7 @@ namespace Mono.Debugging.Client { readonly Dictionary breakpoints = new Dictionary (); readonly Dictionary resolvedExpressionCache = new Dictionary (); + private readonly List assemblies = new List (); readonly InternalDebuggerSession frontend; readonly object slock = new object (); readonly object breakpointStoreLock = new object (); @@ -300,6 +302,26 @@ namespace Mono.Debugging.Client get; private set; } + /// + /// Gets assemblies from the debugger session. + /// + public Assembly[] GetAssemblies () + { + lock (assemblies) { + return assemblies.ToArray (); + } + } + + /// + /// Gets assemblies from the debugger session but filter by the specific process ID . + /// + internal Assembly[] GetAssemblies (long processId) + { + lock (assemblies) { + return assemblies.Where (a => a.ProcessId == processId).ToArray (); + } + } + /// /// Gets or sets the breakpoint store for the debugger session. /// @@ -1302,9 +1324,19 @@ namespace Mono.Debugging.Client internal protected void OnAssemblyLoaded (string assemblyLocation) { - AssemblyLoaded?.Invoke (this, new AssemblyEventArgs (assemblyLocation)); + var assembly = new Assembly (assemblyLocation); + OnAssemblyLoaded (assembly); } - + + internal protected void OnAssemblyLoaded (Assembly assembly) + { + lock (assemblies) { + assemblies.Add (assembly); + } + + AssemblyLoaded?.Invoke (this, new AssemblyEventArgs (assembly)); + } + internal protected void SetBusyState (BusyStateEventArgs args) { BusyStateChanged?.Invoke (this, args); diff --git a/Mono.Debugging/Mono.Debugging.Client/ProcessInfo.cs b/Mono.Debugging/Mono.Debugging.Client/ProcessInfo.cs index 99c80f5..5ba023a 100644 --- a/Mono.Debugging/Mono.Debugging.Client/ProcessInfo.cs +++ b/Mono.Debugging/Mono.Debugging.Client/ProcessInfo.cs @@ -78,5 +78,13 @@ namespace Mono.Debugging.Client { return session.GetThreads (id); } + + /// + /// Gets assemblies from the debugger session that matches the process ID. + /// + public Assembly[] GetAssemblies () + { + return session.GetAssemblies (id); + } } } -- cgit v1.2.3 From 02f592209c5a1b1b07dfcb0f630d0b5e4e40fdc7 Mon Sep 17 00:00:00 2001 From: Jonathan CHang Date: Tue, 19 Jul 2022 09:44:02 -0500 Subject: support dynamic assembly --- Mono.Debugging.Soft/SoftDebuggerSession.cs | 22 +++++++++++----------- Mono.Debugging/Mono.Debugging.Client/Assembly.cs | 9 +++++++-- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Mono.Debugging.Soft/SoftDebuggerSession.cs b/Mono.Debugging.Soft/SoftDebuggerSession.cs index 5661168..5dc4f89 100644 --- a/Mono.Debugging.Soft/SoftDebuggerSession.cs +++ b/Mono.Debugging.Soft/SoftDebuggerSession.cs @@ -2262,19 +2262,17 @@ namespace Mono.Debugging.Soft private void HandleAssemblyLoaded (AssemblyMirror asm) { - var symbolStatus = string.Empty; - var assemblyName = string.Empty; - var hasSymbol = false; var name = asm.GetName (); var assemblyObject = asm.GetAssemblyObject (); - if (!asm.IsDynamic) { + bool isDynamic = asm.IsDynamic; + string assemblyName; + bool hasSymbol; + if (!isDynamic) { var metaData = asm.GetMetadata (); - symbolStatus = metaData.MainModule.HasSymbols == true ? "Symbol loaded" : "Skipped loading symbols"; assemblyName = metaData.MainModule.Name; hasSymbol = metaData.MainModule.HasSymbols; } else { - symbolStatus = "Skipped loading symbol (dynamic)"; - assemblyName = "Dynamic assembly"; + assemblyName = string.Empty; hasSymbol = false; } var assembly = new Assembly ( @@ -2282,16 +2280,18 @@ namespace Mono.Debugging.Soft asm.Location, true, hasSymbol, - symbolStatus, - "", + string.Empty, + string.Empty, -1, name.Version.Major.ToString (), // TODO: module time stamp - "", + string.Empty, assemblyObject.Address.ToString (), string.Format ("[{0}]{1}", asm.VirtualMachine.TargetProcess.Id, asm.VirtualMachine.TargetProcess.ProcessName), asm.Domain.FriendlyName, - asm.VirtualMachine.TargetProcess.Id + asm.VirtualMachine.TargetProcess.Id, + hasSymbol, + isDynamic ); OnAssemblyLoaded (assembly); diff --git a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs index 4a9ad60..966e9e6 100644 --- a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs +++ b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs @@ -28,7 +28,7 @@ namespace Mono.Debugging.Client { public class Assembly { - public Assembly (string name, string path, bool optimized, bool userCode, string symbolStatus, string symbolFile, int? order, string version, string timestamp, string address, string process, string appdomain, long? processId) + public Assembly (string name, string path, bool optimized, bool userCode, string symbolStatus, string symbolFile, int? order, string version, string timestamp, string address, string process, string appdomain, long? processId, bool hasSymbol = false, bool isDynamic = false) { Name = name; Path = path; @@ -43,7 +43,8 @@ namespace Mono.Debugging.Client Version = version; UserCode = userCode; ProcessId = processId; - + IsDynamic = isDynamic; + HasSymbol = hasSymbol; } public Assembly (string path) { @@ -75,5 +76,9 @@ namespace Mono.Debugging.Client public string AppDomain { get; private set; } public long? ProcessId { get; private set; } = -1; + + public bool HasSymbol { get; private set; } + + public bool IsDynamic { get; private set; } } } \ No newline at end of file -- cgit v1.2.3 From ffbd0804f023ecb353e86c859730807d81c8d3dc Mon Sep 17 00:00:00 2001 From: Jonathan CHang Date: Tue, 19 Jul 2022 12:43:23 -0500 Subject: make naming in assembly more consistant hassymbol's' --- Mono.Debugging/Mono.Debugging.Client/Assembly.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs index 966e9e6..0e9dea1 100644 --- a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs +++ b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs @@ -44,7 +44,7 @@ namespace Mono.Debugging.Client UserCode = userCode; ProcessId = processId; IsDynamic = isDynamic; - HasSymbol = hasSymbol; + HasSymbols = hasSymbol; } public Assembly (string path) { @@ -77,7 +77,7 @@ namespace Mono.Debugging.Client public long? ProcessId { get; private set; } = -1; - public bool HasSymbol { get; private set; } + public bool HasSymbols { get; private set; } public bool IsDynamic { get; private set; } } -- cgit v1.2.3 From fc4916f2d190fee86efda9b1d97a2ca54ddaacd3 Mon Sep 17 00:00:00 2001 From: Jonathan CHang Date: Wed, 20 Jul 2022 13:03:44 -0500 Subject: add definition for assembly class and attributes. --- Mono.Debugging/Mono.Debugging.Client/Assembly.cs | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs index 0e9dea1..a2b34e6 100644 --- a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs +++ b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs @@ -28,6 +28,39 @@ namespace Mono.Debugging.Client { public class Assembly { + /// + /// Represent the assembly loaded during the debugging session. This dataclass will be used in the modules pad view for display. + /// + /// + /// String represent the name of the assembly. + /// + /// String represent the local path of the assembly is loaded from. + /// + /// Boolean shows if the assembly has been optimized, true if the assembly is optimized. + /// + /// Boolean show if the assembly is considered 'user code' by a debugger that supports 'Just My Code'.True if it's considered. + /// + /// String represent the Description on if symbols were found for the assembly (ex: 'Symbols Loaded', 'Symbols not found', etc. + /// + /// String represent the Logical full path to the symbol file. The exact definition is implementation defined. + /// + /// Integer indicating the order in which the assembly was loaded. + /// + /// String represent the version of assembly. + /// + /// String represent the time when the assembly was built in the units of UNIX timestamp formatted as a 64-bit unsigned decimal number in a string. + /// + /// String resent the Address where the assembly was loaded as a 64-bit unsigned decimal number. + /// + /// String represent the process name and process ID the assembly is loaded. + /// + /// String indicates the name of the AppDomain where the assembly is loaded. + /// + /// Long represent the process ID the assembly is loaded. + /// + /// Bool value indicate if the assembly is a dynamic. Mainly use for mono project. public Assembly (string name, string path, bool optimized, bool userCode, string symbolStatus, string symbolFile, int? order, string version, string timestamp, string address, string process, string appdomain, long? processId, bool hasSymbol = false, bool isDynamic = false) { Name = name; -- cgit v1.2.3 From 3d60ed660b656a3ab8ea5e4d104517190957d4ec Mon Sep 17 00:00:00 2001 From: Jonathan CHang Date: Thu, 21 Jul 2022 12:55:44 -0500 Subject: optimize documentation for assembly class --- Mono.Debugging/Mono.Debugging.Client/Assembly.cs | 82 ++++++++++++++---------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs index a2b34e6..0963750 100644 --- a/Mono.Debugging/Mono.Debugging.Client/Assembly.cs +++ b/Mono.Debugging/Mono.Debugging.Client/Assembly.cs @@ -26,41 +26,11 @@ using System; namespace Mono.Debugging.Client { + /// + /// Represents the assembly loaded during the debugging session. + /// public class Assembly { - /// - /// Represent the assembly loaded during the debugging session. This dataclass will be used in the modules pad view for display. - /// - /// - /// String represent the name of the assembly. - /// - /// String represent the local path of the assembly is loaded from. - /// - /// Boolean shows if the assembly has been optimized, true if the assembly is optimized. - /// - /// Boolean show if the assembly is considered 'user code' by a debugger that supports 'Just My Code'.True if it's considered. - /// - /// String represent the Description on if symbols were found for the assembly (ex: 'Symbols Loaded', 'Symbols not found', etc. - /// - /// String represent the Logical full path to the symbol file. The exact definition is implementation defined. - /// - /// Integer indicating the order in which the assembly was loaded. - /// - /// String represent the version of assembly. - /// - /// String represent the time when the assembly was built in the units of UNIX timestamp formatted as a 64-bit unsigned decimal number in a string. - /// - /// String resent the Address where the assembly was loaded as a 64-bit unsigned decimal number. - /// - /// String represent the process name and process ID the assembly is loaded. - /// - /// String indicates the name of the AppDomain where the assembly is loaded. - /// - /// Long represent the process ID the assembly is loaded. - /// - /// Bool value indicate if the assembly is a dynamic. Mainly use for mono project. public Assembly (string name, string path, bool optimized, bool userCode, string symbolStatus, string symbolFile, int? order, string version, string timestamp, string address, string process, string appdomain, long? processId, bool hasSymbol = false, bool isDynamic = false) { Name = name; @@ -79,39 +49,85 @@ namespace Mono.Debugging.Client IsDynamic = isDynamic; HasSymbols = hasSymbol; } + public Assembly (string path) { Path = path; } + /// + /// Represents the name of the assembly. + /// public string Name { get; private set; } + /// + /// Represents the local path of the assembly is loaded from. + /// public string Path { get; private set; } + /// + /// Shows if the assembly has been optimized, true if the assembly is optimized. + /// public bool Optimized { get; private set; } + /// + /// Shows if the assembly is considered 'user code' by a debugger that supports 'Just My Code'.True if it's considered. + /// public bool UserCode { get; private set; } + /// + /// Represents the Description on if symbols were found for the assembly (ex: 'Symbols Loaded', 'Symbols not found', etc. + /// public string SymbolStatus { get; private set; } + /// + /// Represents the Logical full path to the symbol file. The exact definition is implementation defined. + /// public string SymbolFile { get; private set; } + /// + /// Represents the order in which the assembly was loaded. + /// public int Order { get; private set; } = -1; + /// + /// Represents the version of assembly. + /// public string Version { get; private set; } + /// + /// Represents the time when the assembly was built in the units of UNIX timestamp formatted as a 64-bit unsigned decimal number in a string. + /// public string TimeStamp { get; private set; } + /// + /// Represents the Address where the assembly was loaded as a 64-bit unsigned decimal number. + /// public string Address { get; private set; } + /// + /// Represent the process name and process ID the assembly is loaded. + /// public string Process { get; private set; } + /// + /// Represent the name of the AppDomain where the assembly is loaded. + /// public string AppDomain { get; private set; } + /// + /// Represent the process ID the assembly is loaded. + /// public long? ProcessId { get; private set; } = -1; + /// + /// Indicates if the assembly has symbol file. Mainly use for mono project. + /// public bool HasSymbols { get; private set; } + /// + /// Indicate if the assembly is a dynamic. Mainly use for mono project. + /// public bool IsDynamic { get; private set; } } } \ No newline at end of file -- cgit v1.2.3