Esempio n. 1
0
        /// <summary>
        /// Loads and initializes the SOS module.
        /// </summary>
        /// <param name="tempDirectory">Temporary directory created to download DAC module</param>
        /// <param name="isDesktop">if true, desktop runtime, else .NET Core runtime</param>
        /// <param name="dacFilePath">The path to DAC that CLRMD loaded or downloaded or null</param>
        /// <param name="dbiFilePath">The path to DBI (for future use) or null</param>
        public void InitializeSOSHost(string tempDirectory, bool isDesktop, string dacFilePath, string dbiFilePath)
        {
            if (_sosLibrary == IntPtr.Zero)
            {
                string sosPath = Path.Combine(SOSPath, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "sos.dll" : "libsos.so");
                try
                {
                    _sosLibrary = DataTarget.PlatformFunctions.LoadLibrary(sosPath);
                }
                catch (DllNotFoundException ex)
                {
                    // This is a workaround for the Microsoft SDK docker images. Can fail when LoadLibrary uses libdl.so to load the SOS module.
                    if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                    {
                        throw new DllNotFoundException("Problem loading SOS module. Try installing libc6-dev (apt-get install libc6-dev) to work around this problem.", ex);
                    }
                    else
                    {
                        throw;
                    }
                }
                if (_sosLibrary == IntPtr.Zero)
                {
                    throw new FileNotFoundException($"SOS module {sosPath} not found");
                }
                IntPtr initializeAddress = DataTarget.PlatformFunctions.GetProcAddress(_sosLibrary, SOSInitialize);
                if (initializeAddress == IntPtr.Zero)
                {
                    throw new EntryPointNotFoundException($"Can not find SOS module initialization function: {SOSInitialize}");
                }
                var initializeFunc = (SOSInitializeDelegate)Marshal.GetDelegateForFunctionPointer(initializeAddress, typeof(SOSInitializeDelegate));

                // SOS depends on that the temp directory ends with "/".
                if (!string.IsNullOrEmpty(tempDirectory) && tempDirectory[tempDirectory.Length - 1] != Path.DirectorySeparatorChar)
                {
                    tempDirectory += Path.DirectorySeparatorChar;
                }

                int result = initializeFunc(
                    ref s_callbacks,
                    Marshal.SizeOf <SOSNetCoreCallbacks>(),
                    tempDirectory,
                    AnalyzeContext.RuntimeModuleDirectory,
                    isDesktop,
                    dacFilePath,
                    dbiFilePath,
                    SymbolReader.IsSymbolStoreEnabled());

                if (result != 0)
                {
                    throw new InvalidOperationException($"SOS initialization FAILED 0x{result:X8}");
                }
                Trace.TraceInformation("SOS initialized: tempDirectory '{0}' dacFilePath '{1}' sosPath '{2}'", tempDirectory, dacFilePath, sosPath);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Metadata locator helper for the DAC.
        /// </summary>
        /// <param name="imagePath">file name and path to module</param>
        /// <param name="imageTimestamp">module timestamp</param>
        /// <param name="imageSize">module image</param>
        /// <param name="localFilePath">local file path of the module</param>
        /// <returns>HRESULT</returns>
        public static int GetICorDebugMetadataLocator(
            [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
            uint imageTimestamp,
            uint imageSize,
            uint pathBufferSize,
            IntPtr pPathBufferSize,
            IntPtr pPathBuffer)
        {
            int hr         = S_OK;
            int actualSize = 0;

            Debug.Assert(pPathBuffer != IntPtr.Zero);
            try
            {
                if (SymbolReader.IsSymbolStoreEnabled())
                {
                    SymbolStoreKey key           = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
                    string         localFilePath = SymbolReader.GetSymbolFile(key);
                    localFilePath += "\0";              // null terminate the string
                    actualSize     = localFilePath.Length;

                    if (pathBufferSize > actualSize)
                    {
                        Marshal.Copy(localFilePath.ToCharArray(), 0, pPathBuffer, actualSize);
                    }
                    else
                    {
                        hr = E_INSUFFICIENT_BUFFER;
                    }
                }
                else
                {
                    hr = E_FAIL;
                }
            }
            catch (Exception ex) when
                (ex is UnauthorizedAccessException ||
                ex is BadImageFormatException ||
                ex is InvalidVirtualAddressException ||
                ex is IOException)
            {
                hr = E_FAIL;
            }

            if (pPathBufferSize != IntPtr.Zero)
            {
                Marshal.WriteInt32(pPathBufferSize, actualSize);
            }

            return(hr);
        }
Esempio n. 3
0
        public static int GetMetadataLocator(
            [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
            uint imageTimestamp,
            uint imageSize,
            [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
            uint mdRva,
            uint flags,
            uint bufferSize,
            IntPtr pMetadata,
            IntPtr pMetadataSize)
        {
            int hr       = unchecked ((int)0x80004005);
            int dataSize = 0;

            Debug.Assert(pMetadata != IntPtr.Zero);

            Stream peStream = null;

            if (imagePath != null && File.Exists(imagePath))
            {
                peStream = SymbolReader.TryOpenFile(imagePath);
            }
            else if (SymbolReader.IsSymbolStoreEnabled())
            {
                SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
                peStream = SymbolReader.GetSymbolStoreFile(key)?.Stream;
            }
            if (peStream != null)
            {
                using (var peReader = new PEReader(peStream, PEStreamOptions.Default))
                {
                    if (peReader.HasMetadata)
                    {
                        PEMemoryBlock metadataInfo = peReader.GetMetadata();
                        unsafe
                        {
                            int size = Math.Min((int)bufferSize, metadataInfo.Length);
                            Marshal.Copy(metadataInfo.GetContent().ToArray(), 0, pMetadata, size);
                        }
                        dataSize = metadataInfo.Length;
                        hr       = 0;
                    }
                }
            }

            if (pMetadataSize != IntPtr.Zero)
            {
                Marshal.WriteInt32(pMetadataSize, dataSize);
            }
            return(hr);
        }
Esempio n. 4
0
        private PEReader GetPEReader(ModuleInfo module)
        {
            if (!_pathToPeReader.TryGetValue(module.FileName, out PEReader reader))
            {
                Stream stream = null;

                string downloadFilePath = module.FileName;
                if (!File.Exists(downloadFilePath))
                {
                    if (SymbolReader.IsSymbolStoreEnabled())
                    {
                        SymbolStoreKey key = PEFileKeyGenerator.GetKey(Path.GetFileName(downloadFilePath), module.TimeStamp, module.FileSize);
                        if (key != null)
                        {
                            // Now download the module from the symbol server
                            downloadFilePath = SymbolReader.GetSymbolFile(key);
                        }
                    }
                }

                if (!string.IsNullOrEmpty(downloadFilePath))
                {
                    try
                    {
                        stream = File.OpenRead(downloadFilePath);
                    }
                    catch (Exception ex) when(ex is DirectoryNotFoundException || ex is FileNotFoundException || ex is UnauthorizedAccessException || ex is IOException)
                    {
                        Trace.TraceError("GetPEReader: exception {0}", ex);
                    }
                    if (stream != null)
                    {
                        reader = new PEReader(stream);
                        _pathToPeReader.Add(module.FileName, reader);
                    }
                }
            }
            return(reader);
        }
Esempio n. 5
0
        /// <summary>
        /// Metadata locator helper for the DAC.
        /// </summary>
        /// <param name="imagePath">file name and path to module</param>
        /// <param name="imageTimestamp">module timestamp</param>
        /// <param name="imageSize">module image</param>
        /// <param name="mvid">not used</param>
        /// <param name="mdRva">not used</param>
        /// <param name="flags">not used</param>
        /// <param name="bufferSize">size of incoming buffer (pMetadata)</param>
        /// <param name="pMetadata">pointer to buffer</param>
        /// <param name="pMetadataSize">size of outgoing metadata</param>
        /// <returns>HRESULT</returns>
        public static int GetMetadataLocator(
            [MarshalAs(UnmanagedType.LPWStr)] string imagePath,
            uint imageTimestamp,
            uint imageSize,
            [MarshalAs(UnmanagedType.LPArray, SizeConst = 16)] byte[] mvid,
            uint mdRva,
            uint flags,
            uint bufferSize,
            IntPtr pMetadata,
            IntPtr pMetadataSize)
        {
            int hr       = S_OK;
            int dataSize = 0;

            Debug.Assert(pMetadata != IntPtr.Zero);
            try
            {
                Stream peStream = null;
                if (imagePath != null && File.Exists(imagePath))
                {
                    peStream = SymbolReader.TryOpenFile(imagePath);
                }
                else if (SymbolReader.IsSymbolStoreEnabled())
                {
                    SymbolStoreKey key = PEFileKeyGenerator.GetKey(imagePath, imageTimestamp, imageSize);
                    peStream = SymbolReader.GetSymbolStoreFile(key)?.Stream;
                }
                if (peStream != null)
                {
                    using (var peReader = new PEReader(peStream, PEStreamOptions.Default))
                    {
                        if (peReader.HasMetadata)
                        {
                            PEMemoryBlock metadataInfo = peReader.GetMetadata();
                            dataSize = metadataInfo.Length;
                            unsafe
                            {
                                int size = Math.Min((int)bufferSize, metadataInfo.Length);
                                Marshal.Copy(metadataInfo.GetContent().ToArray(), 0, pMetadata, size);
                            }
                        }
                        else
                        {
                            hr = E_FAIL;
                        }
                    }
                }
                else
                {
                    hr = E_FAIL;
                }
            }
            catch (Exception ex) when
                (ex is UnauthorizedAccessException ||
                ex is BadImageFormatException ||
                ex is InvalidVirtualAddressException ||
                ex is IOException)
            {
                hr = E_FAIL;
            }
            if (pMetadataSize != IntPtr.Zero)
            {
                Marshal.WriteInt32(pMetadataSize, dataSize);
            }
            return(hr);
        }