예제 #1
0
        public void EvaluateOnFrames(ITestSettings settings)
        {
            this.TestPurpose("To check evalution on different frame with different variable types.");
            this.WriteSettings(settings);

            this.Comment("Open the debugge with a initialization.");
            IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Expression);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Configure launch.");
                runner.Launch(settings.DebuggerSettings, debuggee, "-fExpression");

                this.Comment("Set a breakpoint so that we can stop at a line.");
                runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.Expression, 19));

                this.Comment("To start debugging and break");
                runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterConfigurationDone();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    IFrameInspector currentFrame;

                    this.Comment("To evaluate on the first frame.");
                    currentFrame = threadInspector.Stack.First();
                    currentFrame.AssertVariables("isCalled", "true");
                    Assert.Equal("true", currentFrame.Evaluate("isCalled||false", EvaluateContext.Watch));
                    currentFrame.AssertEvaluateAsDouble("d", EvaluateContext.Watch, 10.1);

                    this.Comment("Switch to next frame then evaluate on that frame.");
                    currentFrame = threadInspector.Stack.ElementAt(1);
                    currentFrame.GetVariable("_f").AssertValueAsFloat(1);
                    currentFrame.AssertEvaluateAsFloat("_f", EvaluateContext.Watch, 1);

                    this.Comment("To evaluate string and vector type on it, the try to enable pretty printing to evaluate again.");
                    currentFrame = threadInspector.Stack.ElementAt(2);
                    currentFrame.GetVariable("vec").AssertValueAsVector(5);
                    currentFrame.AssertEvaluateAsVector("vec", EvaluateContext.Watch, 5);

                    this.Comment("To evaluate some special values on the fourth frame.");
                    currentFrame = threadInspector.Stack.ElementAt(3);
                    currentFrame.AssertEvaluateAsDouble("mydouble=1.0", EvaluateContext.Watch, 1);
                    currentFrame.GetVariable("mynull").AssertValueAsChar('\0');

                    this.Comment("To evaluate class on stack on the fifth frame.");
                    currentFrame = threadInspector.Stack.ElementAt(4);
                    IVariableInspector varInspector;
                    varInspector = currentFrame.GetVariable("student");
                    Assert.Equal("10", varInspector.GetVariable("age").Value);
                    Assert.Equal("19", currentFrame.Evaluate("student.age=19", EvaluateContext.Watch));

                    this.Comment("To evaluate array on the sixth frame.");
                    currentFrame = threadInspector.Stack.ElementAt(5);
                    Assert.Equal("10", currentFrame.Evaluate("*(pArr+1)=10", EvaluateContext.Watch));
                    Assert.Equal("100", currentFrame.Evaluate("arr[0]=100", EvaluateContext.Watch));
                }


                this.Comment("Continue to run to exist.");
                runner.Expects.TerminatedEvent().AfterContinue();

                runner.DisconnectAndVerify();
            }
        }
예제 #2
0
        public void DataTipBasic(ITestSettings settings)
        {
            this.TestPurpose("To test evaluation in datatip.");
            this.WriteSettings(settings);

            IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Expression);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Configure launch.");
                runner.Launch(settings.DebuggerSettings, debuggee, "-fExpression");

                this.Comment("To set a breakpoint so that we can stop at somewhere for evaluation.");
                runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.Expression, 19));

                this.Comment("To start debugging and break");
                runner.Expects.StoppedEvent(StoppedReason.Breakpoint).AfterConfigurationDone();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    IFrameInspector currentFrame;

                    this.Comment("To evaluate in datatip on the first frame.");
                    currentFrame = threadInspector.Stack.First();
                    Assert.Equal("true", currentFrame.Evaluate("isCalled", EvaluateContext.DataTip));
                    currentFrame.AssertEvaluateAsDouble("d", EvaluateContext.DataTip, 10.1);

                    // We only verify the major contents in datatip
                    Assert.Contains(@"accumulate(int)", currentFrame.Evaluate("accumulate", EvaluateContext.DataTip), StringComparison.Ordinal);

                    this.Comment("To evaluate in datatip on the fourth frame.");
                    currentFrame = threadInspector.Stack.ElementAt(3);
                    currentFrame.AssertEvaluateAsDouble("mydouble", EvaluateContext.DataTip, double.PositiveInfinity);
                    currentFrame.AssertEvaluateAsChar("mynull", EvaluateContext.DataTip, '\0');

                    this.Comment("To evaluate in datatip on the fifth frame.");
                    currentFrame = threadInspector.Stack.ElementAt(4);
                    currentFrame.AssertEvaluateAsObject("student", EvaluateContext.DataTip, "name", @"""John""", "age", "10");
                    Assert.Matches(@"0x[0-9A-Fa-f]+", currentFrame.Evaluate("pStu", EvaluateContext.DataTip));

                    this.Comment("To evaluate in datatip on the sixth frame.");
                    currentFrame = threadInspector.Stack.ElementAt(5);
                    currentFrame.AssertEvaluateAsIntArray("arr", EvaluateContext.DataTip, 0, 1, 2, 3, 4);
                    Assert.Matches(@"0x[0-9A-Fa-f]+", currentFrame.Evaluate("pArr", EvaluateContext.DataTip));

                    this.Comment("To evaluate in datatip on the seventh frame.");
                    currentFrame = threadInspector.Stack.ElementAt(6);
                    Assert.Equal("true", currentFrame.Evaluate("mybool", EvaluateContext.DataTip));
                    Assert.Equal("100", currentFrame.Evaluate("myint", EvaluateContext.DataTip));
                    currentFrame.AssertEvaluateAsFloat("myfloat", EvaluateContext.DataTip, 299);
                    currentFrame.AssertEvaluateAsDouble("mydouble", EvaluateContext.DataTip, 321);
                    currentFrame.AssertEvaluateAsChar("mychar", EvaluateContext.DataTip, 'A');
                    currentFrame.AssertEvaluateAsWChar("mywchar", EvaluateContext.DataTip, 'z');
                }

                this.Comment("Continue to run to exist.");
                runner.Expects.TerminatedEvent().AfterContinue();

                runner.DisconnectAndVerify();
            }
        }
예제 #3
0
        public void ExecutionStepRecursiveCall(ITestSettings settings)
        {
            this.TestPurpose("Verify steps should work when debugging recursive call");
            this.WriteSettings(settings);

            this.Comment("Open the kitchen sink debuggee for execution tests.");
            IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Execution);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Configure launch");
                runner.Launch(settings.DebuggerSettings, debuggee, "-fCalling");

                this.Comment("Set initial function breakpoints");
                FunctionBreakpoints funcBp = new FunctionBreakpoints("Calling::CoreRun()");
                runner.SetFunctionBreakpoints(funcBp);

                this.Comment("Launch and run until hit function breakpoint in the entry of calling");
                runner.ExpectBreakpointAndStepToTarget(SinkHelper.Calling, startLine: 47, targetLine: 48).AfterConfigurationDone();

                this.Comment("Step over to go to the entry of recursive call");
                runner.Expects.HitStepEvent(SinkHelper.Calling, 49).AfterStepOver();

                this.Comment("Step in the recursive call");
                runner.ExpectStepAndStepToTarget(SinkHelper.Calling, startLine: 25, targetLine: 26).AfterStepIn();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Set count = 2");
                    IFrameInspector currentFrame = threadInspector.Stack.First();
                    currentFrame.GetVariable("count").Value = "2";

                    this.Comment("Verify there is only one 'recursiveCall' frames");
                    threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*");
                }

                this.Comment("Step over and then step in the recursive call once again");
                runner.Expects.HitStepEvent(SinkHelper.Calling, 29).AfterStepOver();
                runner.ExpectStepAndStepToTarget(SinkHelper.Calling, startLine: 25, targetLine: 26).AfterStepIn();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Verify there are two 'recursiveCall' frames");
                    threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*");

                    this.Comment("Set a source breakpoint in recursive call");
                    SourceBreakpoints srcBp = debuggee.Breakpoints(SinkHelper.Calling, 26);
                    runner.SetBreakpoints(srcBp);
                }

                this.Comment("Step over the recursive call and hit the source breakpoint");
                runner.Expects.HitStepEvent(SinkHelper.Calling, 29).AfterStepOver();
                runner.Expects.HitBreakpointEvent(SinkHelper.Calling, 26).AfterStepOver();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Verify there are three 'recursiveCall' frames");
                    threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "recursiveCall.*", "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*");
                }

                this.Comment("Try to step out twice from recursive call");
                runner.ExpectStepAndStepToTarget(SinkHelper.Calling, 29, 30).AfterStepOut();
                runner.ExpectStepAndStepToTarget(SinkHelper.Calling, 29, 30).AfterStepOut();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Verify 'recursiveCall' return back only one frame");
                    threadInspector.AssertStackFrameNames(true, "recursiveCall.*", "Calling::CoreRun.*", "Feature::Run.*", "main.*");
                }

                this.Comment("Step over from recursive call");
                runner.ExpectStepAndStepToTarget(SinkHelper.Calling, 49, 50).AfterStepOver();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Verify there is not 'recursiveCall' frame");
                    threadInspector.AssertStackFrameNames(true, "Calling::CoreRun.*", "Feature::Run.*", "main.*");
                }

                this.Comment("Verify stop debugging");
                runner.DisconnectAndVerify();
            }
        }
예제 #4
0
 public void CompileKitchenSinkForExecution(ITestSettings settings)
 {
     this.TestPurpose("Compiles the kitchen sink debuggee for execution tests.");
     this.WriteSettings(settings);
     IDebuggee debuggee = SinkHelper.OpenAndCompile(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Execution);
 }
예제 #5
0
        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();
            }
        }
예제 #6
0
        public void ThreadingBasic(ITestSettings settings)
        {
            this.TestPurpose("Test basic multithreading scenario.");
            this.WriteSettings(settings);

            IDebuggee debuggee = SinkHelper.Open(this, settings.CompilerSettings, DebuggeeMonikers.KitchenSink.Threading);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Launching debuggee. Run until multiple threads are running.");
                runner.Launch(settings.DebuggerSettings, debuggee, "-fThreading");
                runner.SetBreakpoints(debuggee.Breakpoints(SinkHelper.Threading, 37));

                runner.Expects.HitBreakpointEvent()
                .AfterConfigurationDone();

                IEnumerable <IThreadInfo> threads    = runner.GetThreads();
                List <string>             loopCounts = new List <string>();

                this.Comment("Inspect threads and find 'loopCount' variable on each worker thread.");
                this.WriteLine("Threads:");
                foreach (var threadInfo in threads)
                {
                    IThreadInspector threadInspector = threadInfo.GetThreadInspector();

                    // Don't look at main thread, just workers
                    if (threadInspector.ThreadId == runner.StoppedThreadId)
                    {
                        continue;
                    }

                    this.Comment("Thread '{0}', Id: {1}".FormatInvariantWithArgs(threadInfo.Name, threadInspector.ThreadId));
                    IFrameInspector threadLoopFrame = threadInspector.Stack.FirstOrDefault(s => s.Name.Contains("ThreadLoop"));

                    // Fail the test if the ThreadLoop frame could not be found
                    if (threadLoopFrame == null)
                    {
                        this.WriteLine("This thread's stack did not contain a frame with 'ThreadLoop'");
                        this.WriteLine("Stack Trace:");
                        foreach (var frame in threadInspector.Stack)
                        {
                            this.WriteLine(frame.Name);
                        }
                        continue;
                    }

                    string variables = threadLoopFrame.Variables.ToReadableString();
                    this.WriteLine("Variables in 'ThreadLoop' frame:");
                    this.WriteLine(variables);

                    // Put the different loopCounts in a list, so they can be verified order agnostic
                    string loopCountValue = threadLoopFrame.GetVariable("loopCount").Value;
                    this.WriteLine("loopCount = {0}", loopCountValue);
                    loopCounts.Add(loopCountValue);
                }

                //Verify all the worker threads were observed
                Assert.True(loopCounts.Contains("0"), "Could not find thread with loop count 0");
                Assert.True(loopCounts.Contains("1"), "Could not find thread with loop count 1");
                Assert.True(loopCounts.Contains("2"), "Could not find thread with loop count 2");
                Assert.True(loopCounts.Contains("3"), "Could not find thread with loop count 3");
                Assert.True(4 == loopCounts.Count, "Expected to find 4 threads, but found " + loopCounts.Count.ToString(CultureInfo.InvariantCulture));

                this.Comment("Run to end.");
                runner.Expects.TerminatedEvent().AfterContinue();

                runner.DisconnectAndVerify();
            }
        }