예제 #1
0
        public static bool GetImageArchitecture(string filepath)
        {
            var file = new PEFile.PEFile(filepath);

            if (file.Header.IsManaged)
            {
                throw new BadImageFormatException(".NET assembly is not supported.");
            }

            return(!file.Header.IsPE64);
        }
예제 #2
0
        static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                return;
            }


            foreach (var file in args)
            {
                Console.WriteLine();
                if (!System.IO.File.Exists(file))
                {
                    Console.WriteLine("{0} does not exists");
                }

                using (PEFile.PEFile peFile = new PEFile.PEFile(file))
                {
                    var header = peFile.Header;

                    Console.WriteLine("Information for file- {0}", file);
                    Console.WriteLine("---------------------------------------------------------");

                    Console.WriteLine("Architecture:    {0}", header.Machine.ToString());
                    Console.WriteLine("Build Date:      {0}", header.TimeDateStamp.ToString());
                    Console.WriteLine("IsManaged:       {0}", header.IsManaged.ToString());

                    string pdbFilePath = string.Empty;
                    Guid   guid;
                    int    age = 0;
                    peFile.GetPdbSignature(out pdbFilePath, out guid, out age);

                    Console.WriteLine("Pdb file Path:   {0}", pdbFilePath);
                    Console.WriteLine("Pdb file guid:   {0}", guid);

                    Console.WriteLine("\nHeader:");
                    Console.WriteLine("MajorOperatingSystemVersion:     {0}", header.MajorOperatingSystemVersion);
                    Console.WriteLine("MajorLinkerVersion:              {0}", header.MajorLinkerVersion);
                    Console.WriteLine("NumberOfSections:                {0}", header.NumberOfSections);
                    Console.WriteLine("NumberOfSymbols:                 {0}", header.NumberOfSymbols);
                    Console.WriteLine("SizeOfImage:                     0x{0:X}", header.SizeOfImage);
                    Console.WriteLine("SizeOfCode:                      0x{0:X}", header.SizeOfCode);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Given an ETL file, returns a list of the full paths to DLLs that were loaded in the trace that need symbolic
        /// information (PDBs) so that the stack traces and CPU samples can be properly resolved.   By default this only
        /// returns NGEN images since these are the ones that need to be resolved and generated at collection time.
        /// </summary>
        public static IEnumerable <string> GetModulesNeedingSymbols(string etlFile, ModuleSymbolOptions options = ModuleSymbolOptions.OnlyNGENImages)
        {
            var images        = new List <ImageData>(300);
            var addressCounts = new Dictionary <Address, int>();

            // Get the name of all DLLS (in the file, and the set of all address-process pairs in the file.
            using (var source = new ETWTraceEventSource(etlFile))
            {
                source.Kernel.ImageGroup += delegate(ImageLoadTraceData data)
                {
                    var fileName = data.FileName;
                    if (fileName.IndexOf(".ni.", StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        // READY_TO_RUN support generate PDBs for ready-to-run images.
                        // TODO can rip this out when we don't package ready-to-run images
                        var windowsIdx = fileName.IndexOf(@"\windows\", StringComparison.OrdinalIgnoreCase);
                        if (0 <= windowsIdx && windowsIdx <= 2)
                        {
                            return;
                        }
                        if (!File.Exists(fileName))
                        {
                            return;
                        }
                        try
                        {
                            using (var peFile = new PEFile.PEFile(fileName))
                            {
                                if (!peFile.IsManagedReadyToRun)
                                {
                                    return;
                                }
                            }
                        }
                        catch { return; }
                    }

                    var processId = data.ProcessID;
                    images.Add(new ImageData(processId, fileName, data.ImageBase, data.ImageSize));
                };

                source.Kernel.StackWalkStack += delegate(StackWalkStackTraceData data)
                {
                    if (data.ProcessID == 0)
                    {
                        return;
                    }
                    var processId = data.ProcessID;
                    for (int i = 0; i < data.FrameCount; i++)
                    {
                        var address = (data.InstructionPointer(i) & 0xFFFFFFFFFFFF0000L) + ((Address)(processId & 0xFFFF));
                        addressCounts[address] = 1;
                    }
                };

                source.Clr.ClrStackWalk += delegate(ClrStackWalkTraceData data)
                {
                    var processId = data.ProcessID;
                    for (int i = 0; i < data.FrameCount; i++)
                    {
                        var address = (data.InstructionPointer(i) & 0xFFFFFFFFFFFF0000L) + ((Address)(processId & 0xFFFF));
                        addressCounts[address] = 1;
                    }
                };

                source.Kernel.PerfInfoSample += delegate(SampledProfileTraceData data)
                {
                    if (data.ProcessID == 0)
                    {
                        return;
                    }
                    var processId = data.ProcessID;
                    var address   = (data.InstructionPointer & 0xFFFFFFFFFFFF0000L) + ((Address)(processId & 0xFFFF));
                    addressCounts[address] = 1;
                };

                source.Process();
            }

            // imageNames is a set of names that we want symbols for.
            var imageNames = new Dictionary <string, string>(100);

            foreach (var image in images)
            {
                if (!imageNames.ContainsKey(image.DllName))
                {
                    for (uint offset = 0; offset < (uint)image.Size; offset += 0x10000)
                    {
                        var key = image.BaseAddress + offset + (uint)(image.ProcessID & 0xFFFF);
                        if (addressCounts.ContainsKey(key))
                        {
                            imageNames[image.DllName] = image.DllName;
                            break;
                        }
                    }
                }
            }

            // Find the PDBS for the given images.
            return(new List <string>(imageNames.Keys));
        }
예제 #4
0
        // These routines find a PDB based on something (either an DLL or a pdb 'signature')
        /// <summary>
        /// Finds the symbol file for 'exeFilePath' that exists on the current machine (we open
        /// it to find the needed info).   Uses the SymbolReader.SymbolPath (including Symbol servers) to 
        /// look up the PDB, and will download the PDB to the local cache if necessary.  
        /// 
        /// This routine looks in the EXEFile to find the PDB Guid signature and then calls FindSymbolFilePath
        /// 
        /// returns null if the pdb can't be found.  
        /// </summary>
        public string FindSymbolFilePathForModule(string dllFilePath)
        {
            Debug.Assert(!IsDisposed);
            try
            {
                dllFilePath = BypassSystem32FileRedirection(dllFilePath);
                if (File.Exists(dllFilePath))
                {
                    using (var peFile = new PEFile.PEFile(dllFilePath))
                    {
                        string pdbName;
                        Guid pdbGuid;
                        int pdbAge;
                        // TODO we get the NGEN pdb if we can.  Is this what we want in general?
                        if (peFile.GetPdbSignature(out pdbName, out pdbGuid, out pdbAge, true))
                        {
                            string fileVersionString = null;
                            var fileVersion = peFile.GetFileVersionInfo();
                            if (fileVersion != null)
                                fileVersionString = fileVersion.FileVersion;

                            // TODO FIX NOW should this be here?
                            m_log.WriteLine("Exe {0} has pdb {1} GUID {2} age {3}", dllFilePath, pdbName, pdbGuid, pdbAge);
                            return FindSymbolFilePath(pdbName, pdbGuid, pdbAge, dllFilePath, fileVersionString);
                        }
                        else
                            m_log.WriteLine("File does not have a codeview debug signature.");
                    }
                }
                else
                    m_log.WriteLine("File does not exist.");
            }
            catch (Exception e)
            {
                m_log.WriteLine("Failure opening PE file: {0}", e.Message);
            }

            m_log.WriteLine("[Failed to find PDB file for {0}]", dllFilePath);
            return null;
        }
예제 #5
0
        private void AddSamplesForDirectory(string directoryPath, StackSourceCallStackIndex directoryStack)
        {
            StackSourceSample sample = null;

            try
            {
                var directory = new FastDirectory(directoryPath);
                foreach (var member in directory.Members)
                {
                    if (member.IsDirectory)
                    {
                        var stack = Interner.CallStackIntern(Interner.FrameIntern("DIR: " + member.Name), directoryStack);
                        AddSamplesForDirectory(Path.Combine(directoryPath, member.Name), stack);
                    }
                    else
                    {
                        var stack = directoryStack;

                        // Allow easy grouping by extension.
                        var ext = Path.GetExtension(member.Name).ToLower();
                        // And whether the DLL/EXE is managed or not.
                        var suffix = "";
                        if (string.Compare(ext, ".dll", true) == 0 || string.Compare(ext, ".exe", true) == 0 || string.Compare(ext, ".winmd", true) == 0)
                        {
                            suffix = "";
                            string fileName = Path.Combine(directoryPath, member.Name);
                            try
                            {
                                using (var peFile = new PEFile.PEFile(fileName))
                                {
                                    suffix = peFile.Header.IsManaged ? " (MANAGED)" : " (UNMANAGED)";
                                    if (peFile.Header.IsPE64)
                                    {
                                        suffix += " (64Bit)";
                                    }
                                    if (peFile.HasPrecompiledManagedCode)
                                    {
                                        if (peFile.IsManagedReadyToRun)
                                        {
                                            short major, minor;
                                            peFile.ReadyToRunVersion(out major, out minor);
                                            suffix += " (ReadyToRun(" + major + "." + minor + "))";
                                        }
                                        else
                                        {
                                            suffix += " (NGEN)";
                                        }
                                    }
                                }
                            }
                            catch (Exception) {
                                m_log.WriteLine("Error: exception looking at file " + fileName);
                                m_log.Flush();
                            }
                        }
                        stack = Interner.CallStackIntern(Interner.FrameIntern("EXT: " + ext + suffix), stack);

                        // Finally the file name itself.
                        stack = Interner.CallStackIntern(Interner.FrameIntern("FILE: " + member.Name), stack);
                        if (sample == null)
                        {
                            sample = new StackSourceSample(this);
                        }

                        sample.Metric     = member.Size;
                        sample.StackIndex = stack;
                        if (m_useWriteTime)
                        {
                            sample.TimeRelativeMSec = (m_nowUtc - member.LastWriteTimeUtc).TotalDays;
                        }
                        else
                        {
                            sample.TimeRelativeMSec = (m_nowUtc - member.LastAccessTimeUtc).TotalDays;
                        }
                        AddSample(sample);

                        m_totalSize += member.Size;
                        int count = SampleIndexLimit;
                        if ((count % 1000) == 0)
                        {
                            m_log.WriteLine("[Processed " + count + " files, size " + (m_totalSize / 1000000).ToString("n0") + " MB in directory scan at " + Path.Combine(directoryPath, member.Name) + " ]");
                        }
                    }
                }
            }
            catch (Exception e)
            {
                m_log.WriteLine("Error processing directory " + directoryPath + ": " + e.Message);
            }
        }