diff --git a/src/Microsoft.SymbolStore/KeyGenerators/ELFCoreKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/ELFCoreKeyGenerator.cs index 69250a93d9..31d5e21bb2 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/ELFCoreKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/ELFCoreKeyGenerator.cs @@ -13,12 +13,14 @@ namespace Microsoft.SymbolStore.KeyGenerators public class ELFCoreKeyGenerator : KeyGenerator { private readonly ELFCoreFile _core; + private readonly string _path; public ELFCoreKeyGenerator(ITracer tracer, SymbolStoreFile file) : base(tracer) { StreamAddressSpace dataSource = new(file.Stream); _core = new ELFCoreFile(dataSource); + _path = file.FileName; } public override bool IsValid() @@ -35,10 +37,18 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) { if (IsValid()) { - return _core.LoadedImages + KeyGenerator[] generators = _core.LoadedImages .Select((ELFLoadedImage loadedImage) => CreateGenerator(loadedImage)) .Where((KeyGenerator generator) => generator != null) - .SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); + .ToArray(); + + if (generators.Length == 0) + { + Tracer.Verbose("ELFCore file `{0}`: missing valid loaded images. No keys will be generated.", _path); + return SymbolStoreKey.EmptyArray; + } + + return generators.SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); } return SymbolStoreKey.EmptyArray; } diff --git a/src/Microsoft.SymbolStore/KeyGenerators/ELFFileKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/ELFFileKeyGenerator.cs index c7de8cc2c3..793c56aab9 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/ELFFileKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/ELFFileKeyGenerator.cs @@ -77,7 +77,13 @@ ex is IndexOutOfRangeException || } string symbolFileName = GetSymbolFileName(); - foreach (SymbolStoreKey key in GetKeys(flags, _path, buildId, symbolFile, symbolFileName)) + SymbolStoreKey[] keys = GetKeys(flags, _path, buildId, symbolFile, symbolFileName).ToArray(); + if (keys.Length == 0 && (flags & (KeyTypeFlags.ClrKeys | KeyTypeFlags.DacDbiKeys)) != 0) + { + string keyType = (flags & KeyTypeFlags.ClrKeys) != 0 ? "CLR" : "DAC/DBI"; + Tracer.Verbose("ELF File `{0}`: file is not the coreclr module `{1}`. No {2} keys will be produced.", _path, CoreClrFileName, keyType); + } + foreach (SymbolStoreKey key in keys) { yield return key; } @@ -91,6 +97,10 @@ ex is IndexOutOfRangeException || // apphost downloaded as the host program name yield return BuildKey(_path, IdentityPrefix, buildId, "apphost"); } + else + { + Tracer.Verbose("ELFfile `{0}`: header type is not an Executable. No host keys will be generated.", _path); + } } } else diff --git a/src/Microsoft.SymbolStore/KeyGenerators/MachCoreKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/MachCoreKeyGenerator.cs index 0f088a0e61..1ceb8755b6 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/MachCoreKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/MachCoreKeyGenerator.cs @@ -12,12 +12,14 @@ namespace Microsoft.SymbolStore.KeyGenerators public class MachCoreKeyGenerator : KeyGenerator { private readonly MachCore _core; + private readonly string _path; public MachCoreKeyGenerator(ITracer tracer, SymbolStoreFile file) : base(tracer) { StreamAddressSpace dataSource = new(file.Stream); _core = new MachCore(dataSource); + _path = file.FileName; } public override bool IsValid() @@ -34,10 +36,18 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) { if (IsValid()) { - return _core.LoadedImages + KeyGenerator[] generators = _core.LoadedImages .Select((MachLoadedImage loadedImage) => CreateGenerator(loadedImage)) .Where((KeyGenerator generator) => generator != null) - .SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); + .ToArray(); + + if (generators.Length == 0) + { + Tracer.Verbose("MachCore file `{0}`: missing valid loaded images. No keys will be generated.", _path); + return SymbolStoreKey.EmptyArray; + } + + return generators.SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); } return SymbolStoreKey.EmptyArray; } diff --git a/src/Microsoft.SymbolStore/KeyGenerators/MachOFatHeaderKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/MachOFatHeaderKeyGenerator.cs index ba6ac92391..d35dab4a67 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/MachOFatHeaderKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/MachOFatHeaderKeyGenerator.cs @@ -29,7 +29,17 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) { if (IsValid()) { - return _machoFatFile.ArchSpecificFiles.Select((file) => new MachOFileKeyGenerator(Tracer, file, _path)).SelectMany((generator) => generator.GetKeys(flags)); + MachOFileKeyGenerator[] generators = _machoFatFile.ArchSpecificFiles + .Select((MachOFile file) => new MachOFileKeyGenerator(Tracer, file, _path)) + .ToArray(); + + if (generators.Length == 0) + { + Tracer.Verbose("Mach-O fat file `{0}`: missing arch-specific slices. No keys will be generated.", _path); + return SymbolStoreKey.EmptyArray; + } + + return generators.SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); } return SymbolStoreKey.EmptyArray; } diff --git a/src/Microsoft.SymbolStore/KeyGenerators/MachOKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/MachOKeyGenerator.cs index ae4f9106d1..b4369ad6ef 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/MachOKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/MachOKeyGenerator.cs @@ -61,7 +61,13 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) { bool symbolFile = _machoFile.Header.FileType == MachHeaderFileType.Dsym; // TODO - mikem 1/23/18 - is there a way to get the name of the "linked" dwarf symbol file - foreach (SymbolStoreKey key in GetKeys(flags, _path, uuid, symbolFile, symbolFileName: null)) + SymbolStoreKey[] keys = GetKeys(flags, _path, uuid, symbolFile, symbolFileName: null).ToArray(); + if (keys.Length == 0 && (flags & (KeyTypeFlags.ClrKeys | KeyTypeFlags.DacDbiKeys)) != 0) + { + string keyType = (flags & KeyTypeFlags.ClrKeys) != 0 ? "CLR" : "DAC/DBI"; + Tracer.Verbose("Mach-O File `{0}`: file is not the coreclr module `{1}`. No {2} keys will be produced.", _path, CoreClrFileName, keyType); + } + foreach (SymbolStoreKey key in keys) { yield return key; } @@ -75,6 +81,10 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) // apphost downloaded as the host program name yield return BuildKey(_path, IdentityPrefix, uuid, "apphost"); } + else + { + Tracer.Verbose("Mach-O file `{0}`: file type `{1}` is not an executable. No host keys will be generated.", _path, _machoFile.Header.FileType); + } } } else diff --git a/src/Microsoft.SymbolStore/KeyGenerators/MinidumpKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/MinidumpKeyGenerator.cs index 324bdfa656..e7e4d22e86 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/MinidumpKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/MinidumpKeyGenerator.cs @@ -11,11 +11,13 @@ namespace Microsoft.SymbolStore.KeyGenerators public class MinidumpKeyGenerator : KeyGenerator { private readonly IAddressSpace _dataSource; + private readonly string _path; public MinidumpKeyGenerator(ITracer tracer, SymbolStoreFile file) : base(tracer) { _dataSource = new StreamAddressSpace(file.Stream); + _path = file.FileName; } public override bool IsValid() @@ -35,9 +37,18 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) try { Minidump dump = new(_dataSource); - return dump.LoadedImages + KeyGenerator[] generators = dump.LoadedImages .Select((MinidumpLoadedImage loadedImage) => new PEFileKeyGenerator(Tracer, loadedImage.Image, loadedImage.ModuleName)) - .SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); + .Where((KeyGenerator g) => g != null && g.IsValid()) + .ToArray(); + + if (generators.Length == 0) + { + Tracer.Verbose("Minidump file `{0}`: missing valid module images. No keys will be generated.", _path); + return SymbolStoreKey.EmptyArray; + } + + return generators.SelectMany((KeyGenerator generator) => generator.GetKeys(flags)); } catch (InvalidVirtualAddressException ex) { diff --git a/src/Microsoft.SymbolStore/KeyGenerators/PEFileKeyGenerator.cs b/src/Microsoft.SymbolStore/KeyGenerators/PEFileKeyGenerator.cs index 5ccfd355a3..d18650b888 100644 --- a/src/Microsoft.SymbolStore/KeyGenerators/PEFileKeyGenerator.cs +++ b/src/Microsoft.SymbolStore/KeyGenerators/PEFileKeyGenerator.cs @@ -67,6 +67,11 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) Tracer.Error("Reading PDB records for {0}: {1}", _path, ex.Message); } + if (pdbs.Length == 0) + { + Tracer.Verbose("PEFile `{0}`: no PDB records found. No symbol keys will be produced.", _path); + } + foreach (PEPdbRecord pdb in pdbs) { if (((flags & KeyTypeFlags.ForceWindowsPdbs) == 0) && pdb.IsPortablePDB) @@ -82,6 +87,11 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) if ((flags & KeyTypeFlags.PerfMapKeys) != 0) { + if (!_peFile.PerfMapsV1.Any()) + { + Tracer.Verbose("PEFile `{0}`: no perfmap records found. No perfmap keys will be produced.", _path); + } + foreach (PEPerfMapRecord perfmapRecord in _peFile.PerfMapsV1) { if (perfmapRecord.Version > FileFormats.PerfMap.PerfMapFile.MaxKnownPerfMapVersion) @@ -94,10 +104,15 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) } // Return keys for SOS modules for a given runtime module - if ((flags & (KeyTypeFlags.ClrKeys)) != 0) + if ((flags & KeyTypeFlags.ClrKeys) != 0) { string coreclrId = BuildId(_peFile.Timestamp, _peFile.SizeOfImage); - foreach (string specialFileName in GetSOSFiles(GetFileName(_path))) + string[] sosFiles = GetSOSFiles(GetFileName(_path)).ToArray(); + if (sosFiles.Length == 0) + { + Tracer.Verbose("PEFile `{0}`: no SOS special files generated for runtime file {1}. No SOS keys will be produced.", _path, GetFileName(_path)); + } + foreach (string specialFileName in sosFiles) { yield return BuildKey(specialFileName, coreclrId); } @@ -107,7 +122,12 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) if ((flags & (KeyTypeFlags.ClrKeys | KeyTypeFlags.DacDbiKeys)) != 0) { string coreclrId = BuildId(_peFile.Timestamp, _peFile.SizeOfImage); - foreach (string specialFileName in GetDACFiles(GetFileName(_path))) + string[] dacFiles = GetDACFiles(GetFileName(_path)).ToArray(); + if (dacFiles.Length == 0) + { + Tracer.Verbose("PEFile `{0}`: no DAC/DBI special files generated for runtime file {1}. No DAC/DBI keys will be produced.", _path, GetFileName(_path)); + } + foreach (string specialFileName in dacFiles) { yield return BuildKey(specialFileName, coreclrId); } @@ -125,6 +145,10 @@ public override IEnumerable GetKeys(KeyTypeFlags flags) // apphost.exe downloaded as the host program name yield return BuildKey(_path, prefix: null, id, "apphost.exe"); } + else + { + Tracer.Verbose("PEfile `{0}`: non-executable (DLL or IL image). No host keys will be generated.", _path); + } } } } diff --git a/src/Tools/dotnet-symbol/Program.cs b/src/Tools/dotnet-symbol/Program.cs index 8aa07ddeb7..dc7d330eb8 100644 --- a/src/Tools/dotnet-symbol/Program.cs +++ b/src/Tools/dotnet-symbol/Program.cs @@ -343,6 +343,8 @@ private IEnumerable GetKeys() foreach (string inputFile in inputFiles) { + Tracer.Verbose($"Generating SymbolStore lookup keys for `{inputFile}`..."); + int count = 0; foreach (KeyGenerator generator in GetKeyGenerators(inputFile)) { KeyTypeFlags flags = KeyTypeFlags.None; @@ -381,9 +383,18 @@ private IEnumerable GetKeys() } foreach (SymbolStoreKeyWrapper wrapper in generator.GetKeys(flags).Select((key) => new SymbolStoreKeyWrapper(key, inputFile))) { + count++; yield return wrapper; } } + if (count > 0) + { + Tracer.Verbose($"Generated {count} SymbolStoreKeys for `{inputFile}`."); + } + else + { + Tracer.Verbose($"Could not generate SymbolStoreKeys for `{inputFile}`."); + } } }