Content-Length: 1086356 | pFad | http://github.com/dotnet/diagnostics/commit/83ec57603f0515206737492d6e579203d3076830

1C Various misc fixes and cleanup (#5421) · dotnet/diagnostics@83ec576 · GitHub
Skip to content

Commit 83ec576

Browse files
author
Mike McLaughlin
authored
Various misc fixes and cleanup (#5421)
This PR is broken down into individual commits for: * Use IHost temp directory in symbol service. Solves problems in containers with R/O tmp directories. * Remove ISymbolService.GetMetaData() and replace with IModuleService.CreateModule call. Move/rename ManagedImageMappingModuleService into ImageMappingMemoryService class. * Add detailed help for finalizequeue and various other managed command. #5235 * Workaround bug in ParseResult.Empty() called by HelpContext constructor. System.CommandLine was throwing an exception because there was no application name under lldb. * Add hosting runtime information in sosstatus command. Fix issue in `sethostruntime` command. Don't print 0.0 for the runtime version. Help diagnose host runtime problems in the future. * Display full exception if collect --diag and use sync command line APIs. Help diagnose exceptions collecting a dump on Windows to diagnose issue #5312. * Workaround issue in .NET 8.0 DAC causing test failures on Alpine. Not worth fixing the 8.0 DAC but causing repeated test failures on Alpine. * Properly clear/release g_sos15/g_sos16 globals. * Bump 8.0/9.0 test versions to latest.
1 parent 7998bb4 commit 83ec576

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+867
-1615
lines changed

eng/Versions.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@
102102
103103
-->
104104
<PropertyGroup>
105-
<MicrosoftNETCoreApp90Version>9.0.0</MicrosoftNETCoreApp90Version>
106-
<MicrosoftNETCoreApp80Version>8.0.8</MicrosoftNETCoreApp80Version>
105+
<MicrosoftNETCoreApp90Version>9.0.4</MicrosoftNETCoreApp90Version>
106+
<MicrosoftNETCoreApp80Version>8.0.15</MicrosoftNETCoreApp80Version>
107107
</PropertyGroup>
108108
<PropertyGroup>
109109
<DotnetRuntimeVersion Condition="'$(DotnetRuntimeVersion)' == ''">default</DotnetRuntimeVersion>

src/Microsoft.Diagnostics.DebugServices.Implementation/CommandService.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ private sealed class CommandGroup
276276
{
277277
private Command _rootCommand;
278278
private readonly Dictionary<string, CommandHandler> _commandHandlers = new();
279+
private readonly ParseResult _emptyParseResult;
279280

280281
//github.com/ <summary>
281282
//github.com/ Create an instance of the command processor;
@@ -284,6 +285,10 @@ private sealed class CommandGroup
284285
public CommandGroup(string commandPrompt = null)
285286
{
286287
_rootCommand = new Command(commandPrompt);
288+
289+
// The actual ParseResult.Empty() has a bug in it where it tries to get the executable name
290+
// and nothing is returned under lldb on Linux causing an index out of range exception.
291+
_emptyParseResult = _rootCommand.Parse(Array.Empty<string>());
287292
}
288293

289294
//github.com/ <summary>
@@ -434,7 +439,7 @@ internal string GetDetailedHelp(Command command, IServiceProvider services, int
434439

435440
// Get the command help
436441
HelpBuilder helpBuilder = new(maxWidth: windowWidth);
437-
HelpContext helpContext = new(helpBuilder, command, console);
442+
HelpContext helpContext = new(helpBuilder, command, console, _emptyParseResult);
438443
helpBuilder.Write(helpContext);
439444

440445
// Get the detailed help if any
@@ -608,7 +613,16 @@ internal string GetDetailedHelp(Command parser, IServiceProvider services)
608613
// requesting help (either the help command or some other command using
609614
// --help) won't work for the command instance that implements it's own
610615
// help (SOS command).
611-
return (string)Invoke(_methodInfoHelp, context: null, parser, services);
616+
string help = (string)Invoke(_methodInfoHelp, context: null, parser, services);
617+
618+
// Replace "{prompt}" with the host debugger's prompt
619+
string prompt = services.GetService<IHost>().HostType switch
620+
{
621+
HostType.Lldb => "(lldb) ",
622+
HostType.DbgEng => "0:000> !",
623+
_ => "> "
624+
};
625+
return help.Replace("{prompt}", prompt);
612626
}
613627

614628
private object Invoke(MethodInfo methodInfo, ParseResult context, Command parser, IServiceProvider services)

src/Microsoft.Diagnostics.DebugServices.Implementation/Host.cs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
using System.Collections.Immutable;
77
using System.Diagnostics;
88
using System.IO;
9+
using System.Runtime.InteropServices;
10+
using System.Text;
911
using Microsoft.Diagnostics.DebugServices;
1012

1113
namespace Microsoft.Diagnostics.DebugServices.Implementation
@@ -92,11 +94,19 @@ public string GetTempDirectory()
9294
{
9395
if (_tempDirectory == null)
9496
{
95-
// Use the SOS process's id if can't get the target's
97+
string tempPath;
98+
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
99+
{
100+
tempPath = Path.GetTempPath();
101+
}
102+
else
103+
{
104+
tempPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".dotnet");
105+
}
106+
// Make the temp directory per SOS session
96107
uint processId = (uint)Process.GetCurrentProcess().Id;
97-
98108
// SOS depends on that the temp directory ends with "/".
99-
_tempDirectory = Path.Combine(Path.GetTempPath(), "sos" + processId.ToString()) + Path.DirectorySeparatorChar;
109+
_tempDirectory = Path.Combine(tempPath, "sos" + processId.ToString()) + Path.DirectorySeparatorChar;
100110
Directory.CreateDirectory(_tempDirectory);
101111
}
102112
return _tempDirectory;

src/Microsoft.Diagnostics.DebugServices.Implementation/ImageMappingMemoryService.cs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
using System.Collections.Generic;
66
using System.Diagnostics;
77
using System.IO;
8+
using System.Linq;
89
using System.Reflection.Metadata;
910
using System.Reflection.PortableExecutable;
11+
using Microsoft.Diagnostics.Runtime;
1012
using Microsoft.FileFormats;
1113

1214
namespace Microsoft.Diagnostics.DebugServices.Implementation
@@ -37,7 +39,7 @@ public ImageMappingMemoryService(ServiceContainer container, IMemoryService memo
3739
container.AddService(memoryService);
3840

3941
_memoryService = memoryService;
40-
_moduleService = managed ? new ManagedImageMappingModuleService(container) : container.GetService<IModuleService>();
42+
_moduleService = managed ? new ManagedModuleService(container) : container.GetService<IModuleService>();
4143
_memoryCache = new MemoryCache(ReadMemoryFromModule);
4244
_recursionProtection = new HashSet<ulong>();
4345

@@ -325,5 +327,58 @@ private static void ApplyRelocations(IModule module, PEReader reader, int dataVA
325327
}
326328
}
327329
}
330+
331+
//github.com/ <summary>
332+
//github.com/ Module service implementation for managed image mapping. Enumerates all managed modules in all runtimes.
333+
//github.com/ </summary>
334+
private sealed class ManagedModuleService : ModuleService
335+
{
336+
private readonly IRuntimeService _runtimeService;
337+
338+
public ManagedModuleService(IServiceProvider services)
339+
: base(services)
340+
{
341+
_runtimeService = services.GetService<IRuntimeService>();
342+
}
343+
344+
//github.com/ <summary>
345+
//github.com/ Get/create the modules dictionary.
346+
//github.com/ </summary>
347+
protected override Dictionary<ulong, IModule> GetModulesInner()
348+
{
349+
Dictionary<ulong, IModule> modules = new();
350+
int moduleIndex = 0;
351+
352+
IEnumerable<IRuntime> runtimes = _runtimeService.EnumerateRuntimes();
353+
if (runtimes.Any())
354+
{
355+
foreach (IRuntime runtime in runtimes)
356+
{
357+
ClrRuntime clrRuntime = runtime.Services.GetService<ClrRuntime>();
358+
if (clrRuntime is not null)
359+
{
360+
foreach (ClrModule clrModule in clrRuntime.EnumerateModules())
361+
{
362+
if (clrModule.ImageBase != 0)
363+
{
364+
IModule module = this.CreateModule(moduleIndex, clrModule);
365+
try
366+
{
367+
modules.Add(module.ImageBase, module);
368+
moduleIndex++;
369+
}
370+
catch (ArgumentException)
371+
{
372+
Trace.TraceError($"GetModulesInner(): duplicate module base '{module}' dup '{modules[module.ImageBase]}'");
373+
}
374+
}
375+
}
376+
}
377+
}
378+
}
379+
380+
return modules;
381+
}
382+
}
328383
}
329384
}

src/Microsoft.Diagnostics.DebugServices.Implementation/ManagedImageMappingModuleService.cs

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/Microsoft.Diagnostics.DebugServices.Implementation/MetadataMappingMemoryService.cs

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,22 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Collections.Immutable;
67
using System.Diagnostics;
78
using System.IO;
89
using System.Linq;
10+
using System.Reflection.PortableExecutable;
911
using Microsoft.Diagnostics.Runtime;
1012
using Microsoft.FileFormats;
1113
using Microsoft.FileFormats.PE;
14+
using Microsoft.SymbolStore;
15+
using Microsoft.SymbolStore.KeyGenerators;
1216

1317
namespace Microsoft.Diagnostics.DebugServices.Implementation
1418
{
1519
//github.com/ <summary>
16-
//github.com/ Memory service wrapper that maps always module's metadata into the address
20+
//github.com/ Memory service wrapper that always maps clrmodule's metadata into the address
1721
//github.com/ space even is some or all of the memory exists in the coredump. lldb returns
1822
//github.com/ zero's (instead of failing the memory read) for missing pages in core dumps
1923
//github.com/ that older (less than 5.0) createdumps generate so it needs this special
@@ -22,6 +26,7 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation
2226
public class MetadataMappingMemoryService : IMemoryService, IDisposable
2327
{
2428
private readonly ServiceContainer _serviceContainer;
29+
private readonly IModuleService _moduleService;
2530
private readonly IMemoryService _memoryService;
2631
private readonly IRuntimeService _runtimeService;
2732
private readonly ISymbolService _symbolService;
@@ -40,6 +45,7 @@ public MetadataMappingMemoryService(ServiceContainer container, IMemoryService m
4045
container.AddService(memoryService);
4146

4247
_memoryService = memoryService;
48+
_moduleService = container.GetService<IModuleService>();
4349
_runtimeService = container.GetService<IRuntimeService>();
4450
_symbolService = container.GetService<ISymbolService>();
4551

@@ -124,7 +130,7 @@ private MetadataRegion FindRegion(ulong address)
124130
// Need to set this before enumerating the runtimes to prevent reentrancy
125131
_regionInitialized = true;
126132

127-
System.Collections.Generic.IEnumerable<IRuntime> runtimes = _runtimeService.EnumerateRuntimes();
133+
IEnumerable<IRuntime> runtimes = _runtimeService.EnumerateRuntimes();
128134
if (runtimes.Any())
129135
{
130136
foreach (IRuntime runtime in runtimes)
@@ -176,32 +182,6 @@ private MetadataRegion FindRegion(ulong address)
176182
return null;
177183
}
178184

179-
private ImmutableArray<byte> GetMetaDataFromAssembly(ClrModule module)
180-
{
181-
Debug.Assert(module.ImageBase != 0);
182-
183-
ImmutableArray<byte> metadata = ImmutableArray<byte>.Empty;
184-
bool isVirtual = module.Layout != ModuleLayout.Flat;
185-
try
186-
{
187-
Stream stream = _memoryService.CreateMemoryStream(module.ImageBase, module.Size > 0 ? module.Size : 4096);
188-
PEFile peFile = new(new StreamAddressSpace(stream), isVirtual);
189-
if (peFile.IsValid())
190-
{
191-
metadata = _symbolService.GetMetadata(module.Name, peFile.Timestamp, peFile.SizeOfImage);
192-
}
193-
else
194-
{
195-
Trace.TraceError($"GetMetaData: {module.ImageBase:X16} not valid PE");
196-
}
197-
}
198-
catch (Exception ex) when (ex is InvalidVirtualAddressException or BadInputFormatException)
199-
{
200-
Trace.TraceError($"GetMetaData: loaded {module.ImageBase:X16} exception {ex.Message}");
201-
}
202-
return metadata;
203-
}
204-
205185
private sealed class MetadataRegion : IComparable<MetadataRegion>
206186
{
207187
private readonly MetadataMappingMemoryService _memoryService;
@@ -242,7 +222,7 @@ private ImmutableArray<byte> GetMetaData()
242222
{
243223
if (_metadata.IsDefault)
244224
{
245-
_metadata = _memoryService.GetMetaDataFromAssembly(_module);
225+
_metadata = _memoryService._moduleService.CreateModule(-1, _module).GetMetadata();
246226
}
247227
return _metadata;
248228
}

src/Microsoft.Diagnostics.DebugServices.Implementation/Module.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public bool? IsFileLayout
110110
{
111111
return false;
112112
}
113-
// Native Windows dlls default to file layout
113+
// Native Windows dlls default to loaded layout
114114
if ((_flags & Flags.IsManaged) == 0 && Target.OperatingSystem == OSPlatform.Windows)
115115
{
116116
return false;
@@ -193,21 +193,21 @@ public ImmutableArray<byte> GetMetadata()
193193
{
194194
try
195195
{
196-
PEReader reader = Services.GetService<PEReader>();
196+
PEReader reader = Services.GetService<PEModule>()?.GetPEReader();
197197
if (reader is not null && reader.HasMetadata)
198198
{
199199
PEMemoryBlock metadataInfo = reader.GetMetadata();
200200
return metadataInfo.GetContent();
201201
}
202202
}
203203
catch (Exception ex) when
204-
(ex is InvalidOperationException ||
205-
ex is BadImageFormatException ||
206-
ex is IOException)
204+
(ex is InvalidOperationException or
205+
BadImageFormatException or
206+
IOException)
207207
{
208208
Trace.TraceError($"GetMetaData: {ex.Message}");
209209
}
210-
return ImmutableArray<byte>.Empty;
210+
return [];
211211
}
212212

213213
#endregion

src/Microsoft.Diagnostics.DebugServices.Implementation/ModuleService.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,22 @@ IEnumerable<IModule> IModuleService.GetModuleFromModuleName(string moduleName)
175175
//github.com/ <summary>
176176
//github.com/ Create a module instance
177177
//github.com/ </summary>
178-
//github.com/ <param name="moduleIndex">artificial index</param>
178+
//github.com/ <param name="moduleIndex">artificial index or -1 for none</param>
179179
//github.com/ <param name="imageBase">module base address</param>
180180
//github.com/ <param name="imageSize">module size</param>
181181
//github.com/ <param name="imageName">module name</param>
182182
//github.com/ <returns>IModule</returns>
183-
IModule IModuleService.CreateModule(int moduleIndex, ulong imageBase, ulong imageSize, string imageName)
183+
//github.com/ <exception cref="ArgumentNullException">thrown if imageBase or imageSize is 0</exception>
184+
public IModule CreateModule(int moduleIndex, ulong imageBase, ulong imageSize, string imageName)
184185
{
186+
if (imageBase == 0)
187+
{
188+
throw new ArgumentNullException(nameof(imageBase));
189+
}
190+
if (imageSize == 0)
191+
{
192+
throw new ArgumentNullException(nameof(imageSize));
193+
}
185194
return new ModuleFromAddress(this, moduleIndex, imageBase, imageSize, imageName);
186195
}
187196

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/dotnet/diagnostics/commit/83ec57603f0515206737492d6e579203d3076830

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy