protected ClrInfo CreateClrInfo()

in src/Microsoft.Diagnostics.Runtime/Implementation/DotNetClrInfoProvider.cs [135:339]


        protected ClrInfo CreateClrInfo(DataTarget dataTarget, ModuleInfo module, ulong runtimeInfo, ClrFlavor flavor)
        {
            Version version;
            int indexTimeStamp = 0;
            int indexFileSize = 0;
            ImmutableArray<byte> buildId = ImmutableArray<byte>.Empty;
            List<DebugLibraryInfo> artifacts = new(8);

            OSPlatform currentPlatform = GetCurrentPlatform();
            OSPlatform targetPlatform = dataTarget.DataReader.TargetPlatform;
            Architecture currentArch = RuntimeInformation.ProcessArchitecture;
            Architecture targetArch = dataTarget.DataReader.Architecture;

            string? dacCurrentPlatform = GetDacFileName(flavor, currentPlatform);
            string? dacTargetPlatform = GetDacFileName(flavor, targetPlatform);
            string? dbiCurrentPlatform = GetDbiFileName(flavor, currentPlatform);
            string? dbiTargetPlatform = GetDbiFileName(flavor, targetPlatform);
            if (runtimeInfo != 0)
            {
                if (ClrRuntimeInfo.TryReadClrRuntimeInfo(dataTarget.DataReader, runtimeInfo, out ClrRuntimeInfo info, out version))
                {
                    if (dataTarget.DataReader.TargetPlatform == OSPlatform.Windows)
                    {
                        indexTimeStamp = info.RuntimePEProperties.TimeStamp;
                        indexFileSize = info.RuntimePEProperties.FileSize;

                        if (dacTargetPlatform is not null)
                        {
                            (int timeStamp, int fileSize) = info.DacPEProperties;
                            if (timeStamp != 0 && fileSize != 0)
                                artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, SymbolProperties.Self, fileSize, timeStamp));
                        }

                        if (dbiTargetPlatform is not null)
                        {
                            (int timeStamp, int fileSize) = info.DbiPEProperties;
                            if (timeStamp != 0 && fileSize != 0)
                                artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, SymbolProperties.Self, fileSize, timeStamp));
                        }
                    }
                    else
                    {
                        buildId = info.RuntimeBuildId;

                        if (dacTargetPlatform is not null)
                        {
                            ImmutableArray<byte> dacBuild = info.DacBuildId;
                            if (!dacBuild.IsDefaultOrEmpty)
                                artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, targetPlatform, SymbolProperties.Self, dacBuild));
                        }

                        if (dbiTargetPlatform is not null)
                        {
                            ImmutableArray<byte> dbiBuild = info.DbiBuildId;
                            if (!dbiBuild.IsDefaultOrEmpty)
                                artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, targetPlatform, SymbolProperties.Self, dbiBuild));
                        }
                    }
                }
            }
            else
            {
                indexTimeStamp = module.IndexTimeStamp;
                indexFileSize = module.IndexFileSize;
                buildId = module.BuildId;
                version = module.Version;
            }

            // Long-name dac
            if (dataTarget.DataReader.TargetPlatform == OSPlatform.Windows && version.Major != 0)
                artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, GetWindowsLongNameDac(flavor, currentArch, targetArch, version), currentArch, SymbolProperties.Coreclr, indexFileSize, indexTimeStamp));

            // Short-name dac under CLR's properties
            if (targetPlatform == currentPlatform)
            {
                // We are debugging the process on the same operating system.
                if (dacCurrentPlatform is not null)
                {
                    bool foundLocalDac = false;

                    // Check if the user has the same CLR installed locally, and if so
                    string? directory = Path.GetDirectoryName(module.FileName);
                    if (!string.IsNullOrWhiteSpace(directory))
                    {
                        string potentialClr = Path.Combine(directory, Path.GetFileName(module.FileName));
                        if (File.Exists(potentialClr))
                        {
                            try
                            {
                                using PEImage peimage = new(File.OpenRead(potentialClr));
                                if (peimage.IndexFileSize == indexFileSize && peimage.IndexTimeStamp == indexTimeStamp)
                                {
                                    string dacFound = Path.Combine(directory, dacCurrentPlatform);
                                    if (File.Exists(dacFound))
                                    {
                                        dacCurrentPlatform = dacFound;
                                        foundLocalDac = true;
                                    }
                                }
                            }
                            catch
                            {
                            }
                        }
                    }

                    if (indexFileSize != 0 && indexTimeStamp != 0)
                    {
                        DebugLibraryInfo dacLibraryInfo = new(DebugLibraryKind.Dac, dacCurrentPlatform, targetArch, SymbolProperties.Coreclr, indexFileSize, indexTimeStamp);
                        if (foundLocalDac)
                            artifacts.Insert(0, dacLibraryInfo);
                        else
                            artifacts.Add(dacLibraryInfo);
                    }

                    if (!buildId.IsDefaultOrEmpty)
                    {
                        DebugLibraryInfo dacLibraryInfo = new(DebugLibraryKind.Dac, dacCurrentPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, buildId);
                        if (foundLocalDac)
                            artifacts.Insert(0, dacLibraryInfo);
                        else
                            artifacts.Add(dacLibraryInfo);
                    }
                }

                if (dbiCurrentPlatform is not null)
                {
                    if (indexFileSize != 0 && indexTimeStamp != 0)
                    {
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiCurrentPlatform, targetArch, SymbolProperties.Coreclr, indexFileSize, indexTimeStamp));
                    }

                    if (!buildId.IsDefaultOrEmpty)
                    {
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiCurrentPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, buildId));
                    }
                }
            }
            else
            {
                // We are debugging the process on a different operating system.
                if (indexFileSize != 0 && indexTimeStamp != 0)
                {
                    // We currently only support cross-os debugging on windows targeting linux or os x runtimes.  So if we have windows properties,
                    // then we only generate one artifact (the target one).
                    if (dacTargetPlatform is not null)
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, SymbolProperties.Coreclr, indexFileSize, indexTimeStamp));

                    if (dbiTargetPlatform is not null)
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, SymbolProperties.Coreclr, indexFileSize, indexTimeStamp));
                }

                if (!buildId.IsDefaultOrEmpty)
                {
                    if (dacTargetPlatform is not null)
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, buildId));

                    if (dbiTargetPlatform is not null)
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, targetPlatform, SymbolProperties.Coreclr, buildId));

                    if (currentPlatform == OSPlatform.Windows)
                    {
                        // If we are running from Windows, we can target Linux and OS X dumps. We do build cross-os, cross-architecture debug libraries to run on Windows x64 or x86
                        if (dacCurrentPlatform is not null)
                            artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacCurrentPlatform, currentArch, currentPlatform, SymbolProperties.Coreclr, buildId));

                        if (dbiCurrentPlatform is not null)
                            artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiCurrentPlatform, currentArch, currentPlatform, SymbolProperties.Coreclr, buildId));
                    }
                }
            }

            // Windows CLRDEBUGINFO resource
            IResourceNode? resourceNode = module.ResourceRoot?.GetChild("RCData")?.GetChild("CLRDEBUGINFO")?.Children.FirstOrDefault();
            if (resourceNode is not null)
            {
                CLR_DEBUG_RESOURCE resource = resourceNode.Read<CLR_DEBUG_RESOURCE>(0);
                if (resource.dwVersion == 0)
                {
                    if (dacTargetPlatform is not null && resource.dwDacTimeStamp != 0 && resource.dwDacSizeOfImage != 0)
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dac, dacTargetPlatform, targetArch, SymbolProperties.Self, resource.dwDacSizeOfImage, resource.dwDacTimeStamp));

                    if (dbiTargetPlatform is not null && resource.dwDbiTimeStamp != 0 && resource.dwDbiSizeOfImage != 0)
                        artifacts.Add(new DebugLibraryInfo(DebugLibraryKind.Dbi, dbiTargetPlatform, targetArch, SymbolProperties.Self, resource.dwDbiSizeOfImage, resource.dwDbiTimeStamp));
                }
            }

            // Do NOT take a dependency on the order of enumerated libraries.  I reserve the right to change this at any time.
            IOrderedEnumerable<DebugLibraryInfo> orderedDebugLibraries = from artifact in EnumerateUnique(artifacts)
                                                                         orderby artifact.Kind,
                                                                                 Path.GetFileName(artifact.FileName) == artifact.FileName, // if we have a full local path, put it first
                                                                                 artifact.ArchivedUnder
                                                                         select artifact;

            ClrInfo result = new(dataTarget, module, version, this)
            {
                Flavor = flavor,
                DebuggingLibraries = orderedDebugLibraries.ToImmutableArray(),
                IndexFileSize = indexFileSize,
                IndexTimeStamp = indexTimeStamp,
                BuildId = buildId,
            };

            return result;
        }