in src/Microsoft.Diagnostics.Runtime/Implementation/DotNetClrInfoProvider.cs [40:109]
private static DacLibrary GetDacLibraryFromPath(ClrInfo clrInfo, string? dacPath, bool ignoreMismatch)
{
OSPlatform currentPlatform = GetCurrentPlatform();
Architecture currentArch = RuntimeInformation.ProcessArchitecture;
if (dacPath is not null)
return CreateDacFromPath(clrInfo, dacPath, ignoreMismatch);
bool foundOne = false;
Exception? exception = null;
IFileLocator? locator = clrInfo.DataTarget.FileLocator;
foreach (DebugLibraryInfo dac in clrInfo.DebuggingLibraries.Where(r => r.Kind == DebugLibraryKind.Dac && r.Platform == currentPlatform && r.TargetArchitecture == currentArch))
{
foundOne = true;
// If we have a full path, use it. We already validated that the CLR matches.
if (Path.GetFileName(dac.FileName) != dac.FileName)
{
dacPath = dac.FileName;
}
else
{
// The properties we are requesting under may not be the actual file properties, so don't request them.
if (locator != null)
{
if (!dac.IndexBuildId.IsDefaultOrEmpty)
{
if (dac.Platform == OSPlatform.Windows)
dacPath = locator.FindPEImage(dac.FileName, SymbolProperties.Coreclr, dac.IndexBuildId, clrInfo.DataTarget.DataReader.TargetPlatform, checkProperties: false);
else if (dac.Platform == OSPlatform.Linux)
dacPath = locator.FindElfImage(dac.FileName, SymbolProperties.Coreclr, dac.IndexBuildId, checkProperties: false);
else if (dac.Platform == OSPlatform.OSX)
dacPath = locator.FindMachOImage(dac.FileName, SymbolProperties.Coreclr, dac.IndexBuildId, checkProperties: false);
}
else if (dac.IndexTimeStamp != 0 && dac.IndexFileSize != 0)
{
if (dac.Platform == OSPlatform.Windows)
dacPath = clrInfo.DataTarget.FileLocator?.FindPEImage(dac.FileName, dac.IndexTimeStamp, dac.IndexFileSize, checkProperties: false);
}
}
}
if (dacPath is not null && File.Exists(dacPath))
{
try
{
// If we get the file from the symbol server, assume mismatches are expected. Sometimes we replace dacs on the symbol
// server to fix bugs. If it's archived under the right path, use it.
return CreateDacFromPath(clrInfo, dacPath, ignoreMismatch: true);
}
catch (Exception ex)
{
exception ??= ex;
dacPath = null;
}
}
}
if (exception is not null)
throw exception;
// We should have had at least one dac enumerated if this is a supported scenario.
if (!foundOne)
throw new InvalidOperationException($"Debugging a '{clrInfo.DataTarget.DataReader.TargetPlatform}' crash is not supported on '{currentPlatform}'.");
throw new FileNotFoundException("Could not find matching DAC for this runtime.");
}