Skip to content

Commit

Permalink
Reference new debugger bits (dotnet#58051)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidwengier authored Dec 2, 2021
1 parent 09c4975 commit 9af4b1e
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 4 deletions.
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
<MicrosoftVisualStudioCompositionVersion>16.9.20</MicrosoftVisualStudioCompositionVersion>
<MicrosoftVisualStudioCoreUtilityVersion>$(VisualStudioEditorNewPackagesVersion)</MicrosoftVisualStudioCoreUtilityVersion>
<MicrosoftVisualStudioDebuggerUIInterfacesVersion>17.2.0-beta.21477.1</MicrosoftVisualStudioDebuggerUIInterfacesVersion>
<MicrosoftVisualStudioDebuggerContractsVersion>17.2.0-beta.21477.1</MicrosoftVisualStudioDebuggerContractsVersion>
<MicrosoftVisualStudioDebuggerContractsVersion>17.2.0-beta.21580.1</MicrosoftVisualStudioDebuggerContractsVersion>
<MicrosoftVisualStudioDebuggerEngineimplementationVersion>17.0.1042805-preview</MicrosoftVisualStudioDebuggerEngineimplementationVersion>
<MicrosoftVisualStudioDebuggerMetadataimplementationVersion>17.0.1042805-preview</MicrosoftVisualStudioDebuggerMetadataimplementationVersion>
<MicrosoftVisualStudioDesignerInterfacesVersion>$(MicrosoftVisualStudioShellPackagesVersion)</MicrosoftVisualStudioDesignerInterfacesVersion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ await RunTestAsync(async path =>
{
MarkupTestFile.GetSpan(source, out var metadataSource, out var expectedSpan);
var (project, symbol) = await CompileAndFindSymbolAsync(path, Location.OnDisk, Location.OnDisk, metadataSource, c => c.GetMember("C.E"));
// Ideally we don't want to pass in true for windowsPdb here, and this is supposed to test that the service ignores non-portable PDBs when the debugger
// tells us they're not portable, but the debugger has a bug at the moment.
var (project, symbol) = await CompileAndFindSymbolAsync(path, Location.OnDisk, Location.OnDisk, metadataSource, c => c.GetMember("C.E"), windowsPdb: true);
// Move the PDB to a path that only our fake debugger service knows about
var pdbFilePath = Path.Combine(path, "SourceLink.pdb");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public PdbFileLocatorService([Import(AllowDefault = true)] ISourceLinkService? s

// TODO: Support windows PDBs: https://github.com/dotnet/roslyn/issues/55834
// TODO: Log results from pdbResult.Log: https://github.com/dotnet/roslyn/issues/57352
if (pdbResult is not null && pdbResult.IsPortablePdb)
if (pdbResult is not null)
{
pdbStream = IOUtilities.PerformIO(() => File.OpenRead(pdbResult.PdbFilePath));
if (pdbStream is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet? opti

// Generate new source or retrieve existing source for the symbol in question
var allowDecompilation = _globalOptions.GetOption(FeatureOnOffOptions.NavigateToDecompiledSources);
var result = _metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, signaturesOnly: false, allowDecompilation, cancellationToken).WaitAndGetResult(cancellationToken);
var result = ThreadingContext.JoinableTaskFactory.Run(() => _metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, signaturesOnly: false, allowDecompilation, cancellationToken));

var vsRunningDocumentTable4 = IServiceProviderExtensions.GetService<SVsRunningDocumentTable, IVsRunningDocumentTable4>(_serviceProvider);
var fileAlreadyOpen = vsRunningDocumentTable4.IsMonikerValid(result.FilePath);
Expand Down
97 changes: 97 additions & 0 deletions src/VisualStudio/Core/Def/PdbSourceDocument/SourceLinkService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Composition;
using System.IO;
using System.Reflection.PortableExecutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host.Mef;
using Microsoft.CodeAnalysis.PdbSourceDocument;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.VisualStudio.Debugger.Contracts.SourceLink;
using Microsoft.VisualStudio.Debugger.Contracts.SymbolLocator;

namespace Microsoft.VisualStudio.LanguageServices.PdbSourceDocument
{
[Export(typeof(ISourceLinkService)), Shared]
internal class SourceLinkService : ISourceLinkService
{
private readonly IDebuggerSymbolLocatorService _debuggerSymbolLocatorService;
private readonly IDebuggerSourceLinkService _debuggerSourceLinkService;

[ImportingConstructor]
[Obsolete(MefConstruction.ImportingConstructorMessage, error: true)]
public SourceLinkService(IDebuggerSymbolLocatorService debuggerSymbolLocatorService, IDebuggerSourceLinkService debuggerSourceLinkService)
{
_debuggerSymbolLocatorService = debuggerSymbolLocatorService;
_debuggerSourceLinkService = debuggerSourceLinkService;
}

public async Task<PdbFilePathResult?> GetPdbFilePathAsync(string dllPath, PEReader peReader, IPdbSourceDocumentLogger? logger, CancellationToken cancellationToken)
{
var hasCodeViewEntry = false;
uint timeStamp = 0;
CodeViewDebugDirectoryData codeViewEntry = default;
using var _ = ArrayBuilder<PdbChecksum>.GetInstance(out var checksums);
foreach (var entry in peReader.ReadDebugDirectory())
{
if (entry.Type == DebugDirectoryEntryType.PdbChecksum)
{
var checksum = peReader.ReadPdbChecksumDebugDirectoryData(entry);
checksums.Add(new PdbChecksum(checksum.AlgorithmName, checksum.Checksum));
}
else if (entry.Type == DebugDirectoryEntryType.CodeView && entry.IsPortableCodeView)
{
hasCodeViewEntry = true;
timeStamp = entry.Stamp;
codeViewEntry = peReader.ReadCodeViewDebugDirectoryData(entry);
}
}

if (!hasCodeViewEntry)
return null;

var pdbInfo = new SymbolLocatorPdbInfo(
Path.GetFileName(codeViewEntry.Path),
codeViewEntry.Guid,
(uint)codeViewEntry.Age,
timeStamp,
checksums.ToImmutable(),
dllPath,
codeViewEntry.Path);

var flags = SymbolLocatorSearchFlags.None; // TODO: Add option to specify ForceMsftSymbolServer and ForceNuGetSymbolServer: https://github.com/dotnet/roslyn/issues/55834
var result = await _debuggerSymbolLocatorService.LocateSymbolFileAsync(pdbInfo, flags, progress: null, cancellationToken).ConfigureAwait(false);

// TODO: Logging: https://github.com/dotnet/roslyn/issues/57352
if (result.Found && result.SymbolFilePath is not null)
{
return new PdbFilePathResult(
result.SymbolFilePath,
result.Status,
result.Log,
result.IsPortablePdb);
}

return null;
}

public async Task<SourceFilePathResult?> GetSourceFilePathAsync(string url, string relativePath, IPdbSourceDocumentLogger? logger, CancellationToken cancellationToken)
{
var result = await _debuggerSourceLinkService.GetSourceLinkAsync(url, relativePath, allowInteractiveLogin: false, cancellationToken).ConfigureAwait(false);

// TODO: Logging: https://github.com/dotnet/roslyn/issues/57352
if (result.Status == SourceLinkResultStatus.Succeeded && result.Path is not null)
{
return new SourceFilePathResult(
result.Path,
result.Log);
}

return null;
}
}
}

0 comments on commit 9af4b1e

Please sign in to comment.