Skip to content

Commit 793b1d6

Browse files
authored
Merge pull request #366 from mono/dev/t-jochang/moduleview
Provide listed assembly in process for moduleview
2 parents 274f3e7 + 3d60ed6 commit 793b1d6

File tree

5 files changed

+227
-6
lines changed

5 files changed

+227
-6
lines changed

Mono.Debugging.Soft/SoftDebuggerSession.cs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@
4949

5050
using StackFrame = Mono.Debugger.Soft.StackFrame;
5151
using System.Collections.Immutable;
52-
52+
using Assembly = Mono.Debugging.Client.Assembly;
53+
5354
namespace Mono.Debugging.Soft
5455
{
5556
public class SoftDebuggerSession : DebuggerSession
@@ -2248,9 +2249,8 @@ void HandleAssemblyLoadEvents (AssemblyLoadEvent[] events)
22482249
if (events.Length > 1 && events.Any (a => a.Assembly != asm))
22492250
throw new InvalidOperationException ("Simultaneous AssemblyLoadEvent for multiple assemblies");
22502251

2251-
OnAssemblyLoaded(asm.Location);
2252-
2253-
RegisterAssembly(asm);
2252+
HandleAssemblyLoaded (asm);
2253+
RegisterAssembly (asm);
22542254
bool isExternal;
22552255
isExternal = !UpdateAssemblyFilters (asm) && userAssemblyNames != null;
22562256

@@ -2260,6 +2260,43 @@ void HandleAssemblyLoadEvents (AssemblyLoadEvent[] events)
22602260
}
22612261
}
22622262

2263+
private void HandleAssemblyLoaded (AssemblyMirror asm)
2264+
{
2265+
var name = asm.GetName ();
2266+
var assemblyObject = asm.GetAssemblyObject ();
2267+
bool isDynamic = asm.IsDynamic;
2268+
string assemblyName;
2269+
bool hasSymbol;
2270+
if (!isDynamic) {
2271+
var metaData = asm.GetMetadata ();
2272+
assemblyName = metaData.MainModule.Name;
2273+
hasSymbol = metaData.MainModule.HasSymbols;
2274+
} else {
2275+
assemblyName = string.Empty;
2276+
hasSymbol = false;
2277+
}
2278+
var assembly = new Assembly (
2279+
assemblyName,
2280+
asm.Location,
2281+
true,
2282+
hasSymbol,
2283+
string.Empty,
2284+
string.Empty,
2285+
-1,
2286+
name.Version.Major.ToString (),
2287+
// TODO: module time stamp
2288+
string.Empty,
2289+
assemblyObject.Address.ToString (),
2290+
string.Format ("[{0}]{1}", asm.VirtualMachine.TargetProcess.Id, asm.VirtualMachine.TargetProcess.ProcessName),
2291+
asm.Domain.FriendlyName,
2292+
asm.VirtualMachine.TargetProcess.Id,
2293+
hasSymbol,
2294+
isDynamic
2295+
);
2296+
2297+
OnAssemblyLoaded (assembly);
2298+
}
2299+
22632300
void RegisterAssembly (AssemblyMirror asm)
22642301
{
22652302
var domain = vm.Version.AtLeast (2, 45) ? asm.Domain : asm.GetAssemblyObject ().Domain;
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
//
2+
// Assembly.cs
3+
//
4+
// Author:
5+
// Jonathan Chang <t-jochang@microsoft.com>
6+
//
7+
// Copyright (c) 2022
8+
//
9+
// Permission is hereby granted, free of charge, to any person obtaining a copy
10+
// of this software and associated documentation files (the "Software"), to deal
11+
// in the Software without restriction, including without limitation the rights
12+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
// copies of the Software, and to permit persons to whom the Software is
14+
// furnished to do so, subject to the following conditions:
15+
//
16+
// The above copyright notice and this permission notice shall be included in
17+
// all copies or substantial portions of the Software.
18+
//
19+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
// THE SOFTWARE.
26+
using System;
27+
namespace Mono.Debugging.Client
28+
{
29+
/// <summary>
30+
/// Represents the assembly loaded during the debugging session.
31+
/// </summary>
32+
public class Assembly
33+
{
34+
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)
35+
{
36+
Name = name;
37+
Path = path;
38+
Optimized = optimized;
39+
SymbolStatus = symbolStatus;
40+
SymbolFile = symbolFile;
41+
Order = order.GetValueOrDefault (-1);
42+
TimeStamp = timestamp;
43+
Address = address;
44+
Process = process;
45+
AppDomain = appdomain;
46+
Version = version;
47+
UserCode = userCode;
48+
ProcessId = processId;
49+
IsDynamic = isDynamic;
50+
HasSymbols = hasSymbol;
51+
}
52+
53+
public Assembly (string path)
54+
{
55+
Path = path;
56+
}
57+
58+
/// <summary>
59+
/// Represents the name of the assembly.
60+
/// </summary>
61+
public string Name { get; private set; }
62+
63+
/// <summary>
64+
/// Represents the local path of the assembly is loaded from.
65+
/// </summary>
66+
public string Path { get; private set; }
67+
68+
/// <summary>
69+
/// Shows if the assembly has been optimized, true if the assembly is optimized.
70+
/// </summary>
71+
public bool Optimized { get; private set; }
72+
73+
/// <summary>
74+
/// Shows if the assembly is considered 'user code' by a debugger that supports 'Just My Code'.True if it's considered.
75+
/// </summary>
76+
public bool UserCode { get; private set; }
77+
78+
/// <summary>
79+
/// Represents the Description on if symbols were found for the assembly (ex: 'Symbols Loaded', 'Symbols not found', etc.
80+
/// </summary>
81+
public string SymbolStatus { get; private set; }
82+
83+
/// <summary>
84+
/// Represents the Logical full path to the symbol file. The exact definition is implementation defined.
85+
/// </summary>
86+
public string SymbolFile { get; private set; }
87+
88+
/// <summary>
89+
/// Represents the order in which the assembly was loaded.
90+
/// </summary>
91+
public int Order { get; private set; } = -1;
92+
93+
/// <summary>
94+
/// Represents the version of assembly.
95+
/// </summary>
96+
public string Version { get; private set; }
97+
98+
/// <summary>
99+
/// 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.
100+
/// </summary>
101+
public string TimeStamp { get; private set; }
102+
103+
/// <summary>
104+
/// Represents the Address where the assembly was loaded as a 64-bit unsigned decimal number.
105+
/// </summary>
106+
public string Address { get; private set; }
107+
108+
/// <summary>
109+
/// Represent the process name and process ID the assembly is loaded.
110+
/// </summary>
111+
public string Process { get; private set; }
112+
113+
/// <summary>
114+
/// Represent the name of the AppDomain where the assembly is loaded.
115+
/// </summary>
116+
public string AppDomain { get; private set; }
117+
118+
/// <summary>
119+
/// Represent the process ID the assembly is loaded.
120+
/// </summary>
121+
public long? ProcessId { get; private set; } = -1;
122+
123+
/// <summary>
124+
/// Indicates if the assembly has symbol file. Mainly use for mono project.
125+
/// </summary>
126+
public bool HasSymbols { get; private set; }
127+
128+
/// <summary>
129+
/// Indicate if the assembly is a dynamic. Mainly use for mono project.
130+
/// </summary>
131+
public bool IsDynamic { get; private set; }
132+
}
133+
}

Mono.Debugging/Mono.Debugging.Client/AssemblyEventArgs.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,24 @@ namespace Mono.Debugging.Client
3030
{
3131
public class AssemblyEventArgs : EventArgs
3232
{
33+
public AssemblyEventArgs (Assembly assembly)
34+
{
35+
Location = assembly.Path;
36+
Assembly = assembly;
37+
}
38+
3339
public AssemblyEventArgs (string location)
3440
{
3541
Location = location;
42+
Assembly = new Assembly (location);
3643
}
3744

3845
public string Location {
3946
get; private set;
4047
}
48+
49+
public Assembly Assembly {
50+
get; private set;
51+
}
4152
}
4253
}

Mono.Debugging/Mono.Debugging.Client/DebuggerSession.cs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
using Mono.Debugging.Backend;
3434
using Mono.Debugging.Evaluation;
35+
using System.Linq;
3536

3637
namespace Mono.Debugging.Client
3738
{
@@ -49,6 +50,7 @@ public abstract class DebuggerSession: IDisposable
4950
{
5051
readonly Dictionary<BreakEvent, BreakEventInfo> breakpoints = new Dictionary<BreakEvent, BreakEventInfo> ();
5152
readonly Dictionary<string, string> resolvedExpressionCache = new Dictionary<string, string> ();
53+
private readonly List<Assembly> assemblies = new List<Assembly> ();
5254
readonly InternalDebuggerSession frontend;
5355
readonly object slock = new object ();
5456
readonly object breakpointStoreLock = new object ();
@@ -300,6 +302,26 @@ public UsageCounter ThreadsPadUsageCounter {
300302
get; private set;
301303
}
302304

305+
/// <summary>
306+
/// Gets assemblies from the debugger session.
307+
/// </summary>
308+
public Assembly[] GetAssemblies ()
309+
{
310+
lock (assemblies) {
311+
return assemblies.ToArray ();
312+
}
313+
}
314+
315+
/// <summary>
316+
/// Gets assemblies from the debugger session but filter by the specific process ID .
317+
/// </summary>
318+
internal Assembly[] GetAssemblies (long processId)
319+
{
320+
lock (assemblies) {
321+
return assemblies.Where (a => a.ProcessId == processId).ToArray ();
322+
}
323+
}
324+
303325
/// <summary>
304326
/// Gets or sets the breakpoint store for the debugger session.
305327
/// </summary>
@@ -1284,9 +1306,19 @@ internal protected void OnTargetDebug (int level, string category, string messag
12841306

12851307
internal protected void OnAssemblyLoaded (string assemblyLocation)
12861308
{
1287-
AssemblyLoaded?.Invoke (this, new AssemblyEventArgs (assemblyLocation));
1309+
var assembly = new Assembly (assemblyLocation);
1310+
OnAssemblyLoaded (assembly);
12881311
}
1289-
1312+
1313+
internal protected void OnAssemblyLoaded (Assembly assembly)
1314+
{
1315+
lock (assemblies) {
1316+
assemblies.Add (assembly);
1317+
}
1318+
1319+
AssemblyLoaded?.Invoke (this, new AssemblyEventArgs (assembly));
1320+
}
1321+
12901322
internal protected void SetBusyState (BusyStateEventArgs args)
12911323
{
12921324
BusyStateChanged?.Invoke (this, args);

Mono.Debugging/Mono.Debugging.Client/ProcessInfo.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,13 @@ public ThreadInfo[] GetThreads ()
7878
{
7979
return session.GetThreads (id);
8080
}
81+
82+
/// <summary>
83+
/// Gets assemblies from the debugger session that matches the process ID.
84+
/// </summary>
85+
public Assembly[] GetAssemblies ()
86+
{
87+
return session.GetAssemblies (id);
88+
}
8189
}
8290
}

0 commit comments

Comments
 (0)