void AddSymbolServer(SymbolStoreSequence storeSequence, IList <string> paths, string defaultPath, bool isCache = false) { var server = new SymbolServer(isCache); for (int i = 0; i < paths.Count; ++i) { var path = paths[i]; if (StadiaSymbolStore.IsStadiaStore(fileSystem, path)) { Trace.WriteLine("Warning: Stadia store not supported in symbol server " + "configuration; it will be ignored."); continue; } else if (HttpSymbolStore.IsHttpStore(path)) { bool hasDownstreamCache = storeSequence.HasCache || !server.IsEmpty; if (!TryAddHttpStore(server, path, hasDownstreamCache)) { continue; } if (isCache) { Trace.WriteLine( $"Warning: '{path}' is being used as a symbol cache, " + "but caching symbols in HTTP symbol stores is not supported."); } else if (i != paths.Count - 1) { Trace.WriteLine( $"Warning: '{path}' is being used as a downstream " + "store, but copying symbols to HTTP symbol stores is not supported."); } } else if (!string.IsNullOrEmpty(path)) { server.AddStore(new StructuredSymbolStore(fileSystem, path)); } else if (!string.IsNullOrEmpty(defaultPath)) { server.AddStore(new StructuredSymbolStore(fileSystem, defaultPath)); } } storeSequence.AddStore(server); }
// symbolPaths is expected to be in the format described above public virtual ISymbolStore Parse(string symbolPaths) { if (symbolPaths == null) { throw new ArgumentNullException("symbolPaths"); } Trace.WriteLine($"Parsing symbol paths: '{symbolPaths}'"); var storeSequence = new SymbolStoreSequence(binaryFileUtil); foreach (var pathElement in symbolPaths.Split(';')) { if (string.IsNullOrEmpty(pathElement)) { continue; } var components = pathElement.Split('*'); if (components.Length > 2 && string.Equals(components[0], "symsrv", StringComparison.OrdinalIgnoreCase)) { // "symsrv*" is followed by the name of the symbol server dll. "symsrv.dll" is // the name of the dll whose behavior we're trying to imitate. if (string.Equals(components[1], "symsrv.dll", StringComparison.OrdinalIgnoreCase)) { AddSymbolServer(storeSequence, components.Skip(2).ToList(), defaultSymbolStorePath); } else { Trace.WriteLine(Strings.UnsupportedSymbolServer(components[1])); } } else if (components.Length > 1 && string.Equals(components[0], "srv", StringComparison.OrdinalIgnoreCase)) { // "srv*" is a shortform for "symsrv*symsrv.dll*" AddSymbolServer(storeSequence, components.Skip(1).ToList(), defaultSymbolStorePath); } else if (components.Length > 1 && string.Equals(components[0], "cache", StringComparison.OrdinalIgnoreCase)) { // Any empty cache paths are replaced with the defalt cache path AddSymbolServer(storeSequence, components.Skip(1).ToList(), defaultCachePath, isCache: true); } // The path element doesn't refer to a symbol server, but it could still be // a Stadia store, an http store, a structured symbol store, or a flat directory. else if (StadiaSymbolStore.IsStadiaStore(fileSystem, pathElement)) { // Stadia stores need to be part of an implicit symbol server just in case // we need to add a local cache downstream from the remote store. var server = new SymbolServer(); if (TryAddStadiaStore(server, storeSequence.HasCache)) { storeSequence.AddStore(server); } } else if (HttpSymbolStore.IsHttpStore(pathElement)) { // HTTP stores need to be part of an implicit symbol server just in case // we need to add a local cache downstream from the remote store. var server = new SymbolServer(); if (TryAddHttpStore(server, pathElement, storeSequence.HasCache)) { storeSequence.AddStore(server); } } else if (StructuredSymbolStore.IsStructuredStore(fileSystem, pathElement)) { storeSequence.AddStore(new StructuredSymbolStore(fileSystem, pathElement)); } else { storeSequence.AddStore( new FlatSymbolStore(fileSystem, binaryFileUtil, pathElement)); } } var jsonRepresentation = JsonConvert.SerializeObject( storeSequence, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }); Trace.WriteLine($"Symbol path parsing result: {jsonRepresentation}"); return(storeSequence); }