public void MapDirectory(ITestSettings settings) { this.TestPurpose("Validate Source Mapping."); this.WriteSettings(settings); IDebuggee debuggee = SourceMappingHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.SourceMapping.Default); // VsDbg is case insensitive on Windows so sometimes stackframe file names might all be lowercase StringComparison comparison = settings.DebuggerSettings.DebuggerType == SupportedDebugger.VsDbg ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure"); LaunchCommand launch = new LaunchCommand(settings.DebuggerSettings, debuggee.OutputPath, false, "-fCalling"); launch.Args.externalConsole = false; this.Comment("Setting up Source File Mappings"); Dictionary <string, string> sourceMappings = new Dictionary <string, string>(); string pathRoot = Path.GetPathRoot(debuggee.SourceRoot); string mgrDirectoryMapping = Path.Combine(debuggee.SourceRoot, SourceMappingHelper.Manager, Path.GetRandomFileName()); string writerDirectoryMapping = Path.Combine(pathRoot, Path.GetRandomFileName(), Path.GetRandomFileName()); string rootDirectoryMapping = Path.Combine(pathRoot, Path.GetRandomFileName()); sourceMappings.Add(Path.Combine(debuggee.SourceRoot, SourceMappingHelper.WriterFolder), writerDirectoryMapping); sourceMappings.Add(Path.Combine(debuggee.SourceRoot, SourceMappingHelper.ManagerFolder), mgrDirectoryMapping); sourceMappings.Add(debuggee.SourceRoot, rootDirectoryMapping); launch.Args.sourceFileMap = sourceMappings; try { if (PlatformUtilities.IsWindows) { // Create all the directories but only some of the files will exist on disk. foreach (var dir in sourceMappings.Values) { Directory.CreateDirectory(dir); } File.Copy(Path.Combine(debuggee.SourceRoot, SourceMappingHelper.WriterFolder, SourceMappingHelper.Writer), Path.Combine(writerDirectoryMapping, SourceMappingHelper.Writer), true); File.Copy(Path.Combine(debuggee.SourceRoot, SourceMappingHelper.Main), Path.Combine(rootDirectoryMapping, SourceMappingHelper.Main), true); } runner.RunCommand(launch); this.Comment("Set Breakpoint"); SourceBreakpoints writerBreakpoints = debuggee.Breakpoints(SourceMappingHelper.Writer, 9); SourceBreakpoints managerBreakpoints = debuggee.Breakpoints(SourceMappingHelper.Manager, 8); runner.SetBreakpoints(writerBreakpoints); runner.SetBreakpoints(managerBreakpoints); runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterConfigurationDone(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IEnumerator <IFrameInspector> frameEnumerator = threadInspector.Stack.GetEnumerator(); // Move to first stack item Assert.True(frameEnumerator.MoveNext()); this.Comment(string.Format(CultureInfo.InvariantCulture, "Verify source path for {0}.", SourceMappingHelper.Writer)); // Since file is there, lowercase the drive letter ValidateMappingToFrame(SourceMappingHelper.Writer, EnsureDriveLetterLowercase(Path.Combine(writerDirectoryMapping, SourceMappingHelper.Writer)), frameEnumerator.Current, comparison); // Move to second stack item Assert.True(frameEnumerator.MoveNext()); this.Comment(string.Format(CultureInfo.InvariantCulture, "Verify source path for {0}.", SourceMappingHelper.Main)); // Since file is there, lowercase the drive letter ValidateMappingToFrame(SourceMappingHelper.Main, EnsureDriveLetterLowercase(Path.Combine(rootDirectoryMapping, SourceMappingHelper.Main)), frameEnumerator.Current, comparison); } runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterContinue(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IEnumerator <IFrameInspector> frameEnumerator = threadInspector.Stack.GetEnumerator(); // Move to first stack item Assert.True(frameEnumerator.MoveNext()); this.Comment(string.Format(CultureInfo.InvariantCulture, "Verify source path for {0}.", SourceMappingHelper.Manager)); // Since file is not there, keep what was passed in ValidateMappingToFrame(SourceMappingHelper.Manager, EnsureDriveLetterLowercase(Path.Combine(mgrDirectoryMapping, SourceMappingHelper.Manager)), frameEnumerator.Current, comparison); // Move to second stack item Assert.True(frameEnumerator.MoveNext()); this.Comment(string.Format(CultureInfo.InvariantCulture, "Verify source path for {0}.", SourceMappingHelper.Main)); // Since file is there, lowercase the drive letter ValidateMappingToFrame(SourceMappingHelper.Main, EnsureDriveLetterLowercase(Path.Combine(rootDirectoryMapping, SourceMappingHelper.Main)), frameEnumerator.Current, comparison); } writerBreakpoints.Remove(9); managerBreakpoints.Remove(8); runner.SetBreakpoints(writerBreakpoints); runner.SetBreakpoints(managerBreakpoints); this.Comment("Continue to end"); runner.Expects.TerminatedEvent().AfterContinue(); runner.DisconnectAndVerify(); } finally { if (PlatformUtilities.IsWindows) { foreach (var dir in sourceMappings.Values) { if (Directory.Exists(dir)) { Directory.Delete(dir, recursive: true); } } } } } }
public void MapSpecificFile(ITestSettings settings) { this.TestPurpose("Validate Specific File Mapping."); this.WriteSettings(settings); IDebuggee debuggee = SourceMappingHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.SourceMapping.Default); // VsDbg is case insensitive on Windows so sometimes stackframe file names might all be lowercase StringComparison comparison = settings.DebuggerSettings.DebuggerType == SupportedDebugger.VsDbg ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal; using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure"); LaunchCommand launch = new LaunchCommand(settings.DebuggerSettings, debuggee.OutputPath, false); launch.Args.externalConsole = false; this.Comment("Setting up Source File Mappings"); Dictionary <string, string> sourceMappings = new Dictionary <string, string>(); string pathRoot = Path.GetPathRoot(debuggee.SourceRoot); string sourceFileMapping = Path.Combine(pathRoot, Path.GetRandomFileName(), SourceMappingHelper.Writer); string compileFileMapping = Path.Combine(debuggee.SourceRoot, SourceMappingHelper.WriterFolder, SourceMappingHelper.Writer); if (PlatformUtilities.IsWindows) { // Move file to the location Directory.CreateDirectory(Path.GetDirectoryName(sourceFileMapping)); File.Copy(compileFileMapping, sourceFileMapping, true); } // Drive letter should be lowercase sourceMappings.Add(compileFileMapping, sourceFileMapping); launch.Args.sourceFileMap = sourceMappings; try { runner.RunCommand(launch); this.Comment("Set Breakpoint"); SourceBreakpoints writerBreakpoints = debuggee.Breakpoints(SourceMappingHelper.Writer, 9); runner.SetBreakpoints(writerBreakpoints); runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterConfigurationDone(); using (IThreadInspector threadInspector = runner.GetThreadInspector()) { IEnumerator <IFrameInspector> frameEnumerator = threadInspector.Stack.GetEnumerator(); // Move to first stack item Assert.True(frameEnumerator.MoveNext()); this.Comment("Verify path is changed for writer.cpp frame"); ValidateMappingToFrame(SourceMappingHelper.Writer, EnsureDriveLetterLowercase(sourceFileMapping), frameEnumerator.Current, comparison); // Move to second stack item Assert.True(frameEnumerator.MoveNext()); this.Comment("Verify path is not changed for main.cpp frame."); ValidateMappingToFrame(SourceMappingHelper.Main, EnsureDriveLetterLowercase(Path.Combine(debuggee.SourceRoot, SourceMappingHelper.Main)), frameEnumerator.Current, comparison); writerBreakpoints.Remove(9); runner.SetBreakpoints(writerBreakpoints); this.Comment("Continue to end"); runner.Expects.TerminatedEvent().AfterContinue(); runner.DisconnectAndVerify(); } } finally { if (PlatformUtilities.IsWindows) { // Cleanup the directory if (Directory.Exists(Path.GetDirectoryName(sourceFileMapping))) { Directory.Delete(Path.GetDirectoryName(sourceFileMapping), true); } } } } }
public void LineBreakpointsBasic(ITestSettings settings) { this.TestPurpose("Tests basic operation of line breakpoints"); this.WriteSettings(settings); IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Breakpoint); using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings)) { this.Comment("Configure launch"); runner.Launch(settings.DebuggerSettings, debuggee, "-fCalling"); // These keep track of all the breakpoints in a source file SourceBreakpoints argumentsBreakpoints = debuggee.Breakpoints(SinkHelper.Arguments, 23); SourceBreakpoints mainBreakpoints = debuggee.Breakpoints(SinkHelper.Main, 33); SourceBreakpoints callingBreakpoints = debuggee.Breakpoints(SinkHelper.Calling, 48); // A bug in clang causes several breakpoint hits in a constructor // See: https://llvm.org/bugs/show_bug.cgi?id=30620 if (settings.CompilerSettings.CompilerType != SupportedCompiler.ClangPlusPlus) { callingBreakpoints.Add(6); } this.Comment("Set initial breakpoints"); runner.SetBreakpoints(argumentsBreakpoints); runner.SetBreakpoints(mainBreakpoints); runner.SetBreakpoints(callingBreakpoints); this.Comment("Launch and run until first breakpoint"); runner.Expects.HitBreakpointEvent(SinkHelper.Arguments, 23) .AfterConfigurationDone(); // A bug in clang causes several breakpoint hits in a constructor // See: https://llvm.org/bugs/show_bug.cgi?id=30620 if (settings.CompilerSettings.CompilerType != SupportedCompiler.ClangPlusPlus) { this.Comment("Continue until second initial breakpoint"); runner.Expects.HitBreakpointEvent(SinkHelper.Calling, 6).AfterContinue(); } this.Comment("Disable third initial breakpoint"); mainBreakpoints.Remove(33); runner.SetBreakpoints(mainBreakpoints); this.Comment("Continue, hit fourth initial breakpoint"); runner.Expects.HitBreakpointEvent(SinkHelper.Calling, 48).AfterContinue(); this.Comment("Set a breakpoint while in break mode"); callingBreakpoints.Add(52); runner.SetBreakpoints(callingBreakpoints); this.Comment("Continue until newly-added breakpoint"); runner.Expects.HitBreakpointEvent(SinkHelper.Calling, 52) .AfterContinue(); this.Comment("Continue until end"); runner.Expects.ExitedEvent() .TerminatedEvent() .AfterContinue(); runner.DisconnectAndVerify(); } }