예제 #1
0
        /// <summary>
        /// Get's a variable, but fails with more detailed message if it doesn't exist. Can be called with child variable names
        /// to follow variable expansion tree.
        /// </summary>
        public static IVariableInspector GetVariable(this IVariableExpander variableExpander, params string[] names)
        {
            Parameter.ThrowIfIsInvalid(names.Length, 0, nameof(names));

            IVariableInspector variableInspector = null;

            foreach (var name in names)
            {
                variableInspector = GetVariablePart(variableExpander, name);
                variableExpander  = variableInspector;
            }
            return(variableInspector);
        }
예제 #2
0
        public void TestSharedLibWithoutSymbol(ITestSettings settings)
        {
            this.TestPurpose("Tests basic bps and source information for shared library without symbols");
            this.WriteSettings(settings);

            IDebuggee debuggee = Debuggee.Open(this, settings.CompilerSettings, Name, DebuggeeMonikers.Optimization.OptimizationWithoutSymbols);

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

                SourceBreakpoints mainBreakpoints = debuggee.Breakpoints(SourceName, 87, 91);

                this.Comment("Set initial breakpoints");
                runner.SetBreakpoints(mainBreakpoints);

                this.Comment("Launch and run until 1st bp");
                runner.Expects.HitBreakpointEvent(SourceName, 87)
                .AfterConfigurationDone();

                this.Comment("Step into the library source");
                runner.Expects.HitStepEvent(SourceName, 89)
                .AfterStepIn();

                this.Comment("Check the stack for debugging shared library without symbols");
                using (IThreadInspector inspector = runner.GetThreadInspector())
                {
                    IFrameInspector currentFrame = inspector.Stack.First();
                    inspector.AssertStackFrameNames(true, "main");

                    this.Comment("run to continue to 2nd bp");
                    runner.Expects.HitBreakpointEvent(SourceName, 91)
                    .AfterContinue();

                    this.Comment("Check the stack for debugging shared library without symbols");
                    currentFrame = inspector.Stack.First();
                    inspector.AssertStackFrameNames(true, "main");
                    this.Comment("Check the local variables in main function");
                    IVariableInspector age = currentFrame.Variables["age"];
                    Assert.Matches("31", age.Value);
                }

                runner.DisconnectAndVerify();
            }
        }
예제 #3
0
        public void TestOptimizedLocals(ITestSettings settings)
        {
            this.TestPurpose("Tests basic local expression which is not been optimized");
            this.WriteSettings(settings);

            IDebuggee debuggee = Debuggee.Open(this, settings.CompilerSettings, Name, DebuggeeMonikers.Optimization.OptimizationWithSymbols);

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

                SourceBreakpoints userDefinedClassBreakpoints = debuggee.Breakpoints(UserDefinedClassName, 54);

                this.Comment("Set initial breakpoints");
                runner.SetBreakpoints(userDefinedClassBreakpoints);

                this.Comment("Launch and run until 1st bp");
                runner.Expects.HitBreakpointEvent(UserDefinedClassName, 54)
                .AfterConfigurationDone();

                this.Comment("Check the un-optimized values");
                using (IThreadInspector inspector = runner.GetThreadInspector())
                {
                    IFrameInspector    currentFrame = inspector.Stack.First();
                    IVariableInspector sum          = currentFrame.Variables["sum"];
                    IVariableInspector first        = currentFrame.Variables["first"];

                    this.Comment("Check the local variables in sub function");
                    Assert.Matches("^0", sum.Value);
                    Assert.Matches("^1", first.Value);

                    this.Comment("Step out");
                    runner.Expects.HitStepEvent(SourceName, 66)
                    .AfterStepOut();

                    this.Comment("Evaluate the expression:");
                    currentFrame = inspector.Stack.First();
                    inspector.AssertStackFrameNames(true, "main");
                }

                runner.DisconnectAndVerify();
            }
        }
예제 #4
0
 public static void AssertValueAsFloat(this IVariableInspector valueInspector, float expectedValue)
 {
     AssertFloatValue(valueInspector.DebuggerRunner.DebuggerSettings, valueInspector.Value, expectedValue);
 }
예제 #5
0
 public static void AssertValueAsIntArray(this IVariableInspector valueInspector, params int[] expectedValue)
 {
     AssertIntArrayValue(valueInspector.DebuggerRunner.DebuggerSettings, valueInspector.Value, expectedValue);
 }
예제 #6
0
 public static void AssertValueAsObject(this IVariableInspector valueInspector, params string[] expectedObjectProperties)
 {
     AssertObjectValue(valueInspector.DebuggerRunner.DebuggerSettings, valueInspector.Value, expectedObjectProperties);
 }
예제 #7
0
 public static void AssertValueAsVector(this IVariableInspector valueInspector, int vectorCount)
 {
     AssertVectorValue(valueInspector.DebuggerRunner.DebuggerSettings, valueInspector.Value, vectorCount);
 }
예제 #8
0
 public static void AssertValueAsWChar(this IVariableInspector valueInspector, char expectedValue)
 {
     AssertWCharValue(valueInspector.DebuggerRunner.DebuggerSettings, valueInspector.Value, expectedValue);
 }
예제 #9
0
 public static void AssertValueAsDouble(this IVariableInspector valueInspector, double expectedValue)
 {
     AssertDoubleValue(valueInspector.DebuggerRunner.DebuggerSettings, valueInspector.Value, expectedValue);
 }
예제 #10
0
        public void TestOptimizedSharedLib(ITestSettings settings)
        {
            this.TestPurpose("Tests basic bps and source information for shared library");
            this.WriteSettings(settings);

            IDebuggee debuggee = Debuggee.Open(this, settings.CompilerSettings, Name, DebuggeeMonikers.Optimization.OptimizationWithSymbols);

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

                SourceBreakpoints mainBreakpoints = debuggee.Breakpoints(SourceName, 87, 89);
                SourceBreakpoints libBreakpoints  = debuggee.Breakpoints(SrcLibName, 9, 12);

                this.Comment("Set initial breakpoints");
                runner.SetBreakpoints(mainBreakpoints);
                runner.SetBreakpoints(libBreakpoints);

                this.Comment("Launch and run until 1st bp");
                runner.Expects.HitBreakpointEvent(SourceName, 87)
                .AfterConfigurationDone();

                //Todo: this has different behavior on Mac, I have logged bug#247895 to track
                //Del said that Different compilers generate symbols differently.
                //Our tests have to be resilient to this fact. The location of the step is reasonable,
                //so this is by design.
                this.Comment("enter into the library source");
                runner.ExpectBreakpointAndStepToTarget(SrcLibName, 8, 9).AfterContinue();

                this.Comment("Step over");
                runner.Expects.HitStepEvent(SrcLibName, 10).AfterStepOver();

                this.Comment("Check the un-optimized values in shared library");
                using (IThreadInspector inspector = runner.GetThreadInspector())
                {
                    IFrameInspector    currentFrame = inspector.Stack.First();
                    IVariableInspector age          = currentFrame.Variables["age"];

                    this.Comment("Check the local variable in sub function");
                    Assert.Matches("31", age.Value);

                    this.Comment("run to continue");
                    if (settings.DebuggerSettings.DebuggerType == SupportedDebugger.Lldb)
                    {
                        runner.Expects.HitBreakpointEvent(SourceName, 89)
                        .AfterContinue();
                        this.Comment("Verify current frame for main func");
                        inspector.AssertStackFrameNames(true, "main");
                    }
                    else
                    {
                        runner.Expects.HitBreakpointEvent(SrcLibName, 12)
                        .AfterContinue();
                        this.Comment("Verify current frame for library func");
                        inspector.AssertStackFrameNames(true, "myClass::DisplayAge");

                        this.Comment("Step out to main entry");
                        runner.Expects.HitBreakpointEvent(SourceName, 89).AfterContinue();

                        this.Comment("Verify current frame for main entry");
                        inspector.AssertStackFrameNames(true, "main");
                    }

                    this.Comment("Evaluate the expression:");
                    //skip the Mac's verification as bug#247893
                    currentFrame = inspector.Stack.First();
                    string strAge = currentFrame.Evaluate("myclass->DisplayAge(30)");

                    if (settings.DebuggerSettings.DebuggerType == SupportedDebugger.Gdb_MinGW ||
                        settings.DebuggerSettings.DebuggerType == SupportedDebugger.Gdb_Cygwin)
                    {
                        Assert.Equal("Cannot evaluate function -- may be inlined", strAge);
                    }
                }

                runner.DisconnectAndVerify();
            }
        }
예제 #11
0
        public void RaisedReThrowException(ITestSettings settings)
        {
            this.TestPurpose("This test checks to see if re-throw exception can work during debugging.");
            this.WriteSettings(settings);

            this.Comment("Set initial debuggee for application");
            IDebuggee debuggee = OpenDebuggee(this, settings, DebuggeeMonikers.Exception.Default);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Launch the application");
                runner.Launch(settings.DebuggerSettings, debuggee, "-CallRaisedReThrowException");

                this.Comment("Set line breakpoints to the lines with entry of try block and catch block");
                SourceBreakpoints bps = debuggee.Breakpoints(srcClassName, 73, 79, 86);
                runner.SetBreakpoints(bps);

                this.Comment("Start debugging and hit the breakpoint in the try block");
                runner.Expects.HitBreakpointEvent(srcClassName, 73).AfterConfigurationDone();

                this.Comment("Continue executing and hit the breakpoint in the frist catch block");
                runner.Expects.HitBreakpointEvent(srcClassName, 79).AfterContinue();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Get current frame object");
                    IFrameInspector currentFrame = threadInspector.Stack.First();

                    this.Comment("Verify current frame when stop at the first catch block");
                    threadInspector.AssertStackFrameNames(true, "myException::RaisedReThrowException.*");

                    this.Comment("Verify the variables of 'errorCode' in the first catch block");
                    currentFrame.AssertVariables("errorCode", "200");

                    this.Comment("Verify step in can work in the first catch block");
                    runner.ExpectStepAndStepToTarget(srcClassName, startLine: 41, targetLine: 42).AfterStepIn();

                    this.Comment("Verify current frame after step in another function");
                    threadInspector.AssertStackFrameNames(true, "myException::EvalFunc.*");

                    this.Comment("Verify step out can work in the first catch block");
                    runner.Expects.HitStepEvent(srcClassName, 79).AfterStepOut();
                }

                this.Comment("Continue to hit the re-throw exception in the first catch block");
                runner.Expects.HitBreakpointEvent(srcClassName, 86).AfterContinue();

                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Get current frame object");
                    IFrameInspector currentFrame = threadInspector.Stack.First();

                    this.Comment("Verify current frame when stop at the second catch block");
                    threadInspector.AssertStackFrameNames(true, "myException::RaisedReThrowException.*");

                    this.Comment("Verify the variables in the second catch block");
                    Assert.Subset(new HashSet <string>()
                    {
                        "var", "this", "errorCode", "ex2"
                    }, currentFrame.Variables.ToKeySet());
                    currentFrame.AssertVariables("var", "400", "errorCode", "400");

                    this.Comment("Verify the exception information in the second catch block");
                    IVariableInspector ex2Var = currentFrame.Variables["ex2"];
                    Assert.Contains("code", ex2Var.Variables.Keys);
                    this.WriteLine("Expected: 400, Actual: {0}", ex2Var.Variables["code"].Value);
                    Assert.Equal("400", ex2Var.Variables["code"].Value);

                    this.Comment("Evaluate a function and verify the the results at the second catch block ");
                    // TODO: Mingw32 was affected by bug #242924, I wil update this once this bug get fixed
                    bool evalNotSupportedInCatch =
                        (settings.DebuggerSettings.DebuggerType == SupportedDebugger.Gdb_MinGW && settings.DebuggerSettings.DebuggeeArchitecture == SupportedArchitecture.x86) ||
                        (settings.DebuggerSettings.DebuggerType == SupportedDebugger.VsDbg && settings.DebuggerSettings.DebuggeeArchitecture == SupportedArchitecture.x64);
                    if (!evalNotSupportedInCatch)
                    {
                        string funEvalResult = currentFrame.Evaluate("EvalFunc(20,20)");
                        this.WriteLine("Expected: 40, Actual: {0}", funEvalResult);
                        Assert.Equal("40", funEvalResult);
                    }
                }

                this.Comment("Verify can step out from a catch block");
                runner.ExpectStopAndStepToTarget(StoppedReason.Step, srcAppName, startLine: 61, targetLine: 64).AfterStepOut();

                this.Comment("Continue to run at the end of the application");
                runner.Expects.TerminatedEvent().AfterContinue();

                runner.DisconnectAndVerify();
            }
        }
예제 #12
0
        public void RaisedHandledException(ITestSettings settings)
        {
            this.TestPurpose("This test checks to see if user handled exception can work during debugging");
            this.WriteSettings(settings);

            this.Comment("Set initial debuggee for application");
            IDebuggee debuggee = OpenDebuggee(this, settings, DebuggeeMonikers.Exception.Default);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Launch the application");
                runner.Launch(settings.DebuggerSettings, debuggee, "-CallRaisedHandledException");

                this.Comment("Set line breakpoints to the lines with entry of try block and catch block");
                SourceBreakpoints bps = debuggee.Breakpoints(srcClassName, 20, 33);
                runner.SetBreakpoints(bps);

                this.Comment("Start debugging and hit the breakpoint in the try block");
                runner.Expects.HitBreakpointEvent(srcClassName, 20).AfterConfigurationDone();

                this.Comment("Step over in the try block");
                runner.Expects.HitStepEvent(srcClassName, 21).AfterStepOver();

                this.Comment("Continue to raise the exception and hit the breakpoint set in the catch block");
                runner.Expects.HitBreakpointEvent(srcClassName, 33).AfterContinue();

                this.Comment("Verify can step over in the catch block");
                runner.Expects.HitStepEvent(srcClassName, 34).AfterStepOver();

                this.Comment("Verify the callstack, variables and evaluation ");
                using (IThreadInspector threadInspector = runner.GetThreadInspector())
                {
                    this.Comment("Get current frame object");
                    IFrameInspector currentFrame = threadInspector.Stack.First();

                    this.Comment("Verify current frame when stop at the catch block");
                    threadInspector.AssertStackFrameNames(true, "myException::RaisedHandledException.*");

                    this.Comment("Verify the variables in the catch block");
                    Assert.Subset(new HashSet <string>()
                    {
                        "result", "global", "this", "a", "errorCode", "ex"
                    }, currentFrame.Variables.ToKeySet());
                    currentFrame.AssertVariables("result", "201", "global", "101", "a", "100");

                    this.Comment("Verify the exception information in the catch block");
                    IVariableInspector exVar = currentFrame.Variables["ex"];
                    Assert.Contains("code", exVar.Variables.Keys);
                    this.WriteLine("Expected: 101, Actual: {0}", exVar.Variables["code"].Value);
                    Assert.Equal("101", exVar.Variables["code"].Value);

                    // TODO: LLDB was affected by bug #240441, I wil update this once this bug get fixed
                    if (settings.DebuggerSettings.DebuggerType != SupportedDebugger.Lldb)
                    {
                        this.Comment("Evaluate an expression and verify the results");
                        string varEvalResult = currentFrame.Evaluate("result=result + 1");
                        this.WriteLine("Expected: 202, Actual: {0}", varEvalResult);
                        Assert.Equal("202", varEvalResult);
                    }

                    this.Comment("Evaluate a function and verify the the results");
                    // TODO: Mingw32 was affected by bug #242924, I wil update this once this bug get fixed
                    bool evalNotSupportedInCatch =
                        (settings.DebuggerSettings.DebuggerType == SupportedDebugger.Gdb_MinGW && settings.DebuggerSettings.DebuggeeArchitecture == SupportedArchitecture.x86) ||
                        (settings.DebuggerSettings.DebuggerType == SupportedDebugger.VsDbg && settings.DebuggerSettings.DebuggeeArchitecture == SupportedArchitecture.x64);
                    if (!evalNotSupportedInCatch)
                    {
                        string funEvalResult = currentFrame.Evaluate("RecursiveFunc(50)");
                        this.WriteLine("Expected: 1, Actual: {0}", funEvalResult);
                        Assert.Equal("1", funEvalResult);
                    }
                }

                this.Comment("Verify can step over after evaluation in the catch block");
                runner.Expects.HitStepEvent(srcClassName, 35).AfterStepOver();

                this.Comment("Continue to run at the end of the application");
                runner.Expects.TerminatedEvent().AfterContinue();

                runner.DisconnectAndVerify();
            }
        }
예제 #13
0
        public void TestFolderol(ITestSettings settings)
        {
            this.TestPurpose("This test checks a bunch of commands and events.");
            this.WriteSettings(settings);

            IDebuggee debuggee = Debuggee.Open(this, settings.CompilerSettings, HelloName, DebuggeeMonikers.HelloWorld.Sample);

            using (IDebuggerRunner runner = CreateDebugAdapterRunner(settings))
            {
                this.Comment("Launch the debuggee");
                runner.Launch(settings.DebuggerSettings, debuggee);

                StoppedEvent stopAtBreak = new StoppedEvent(StoppedReason.Breakpoint);

                // VsDbg does not fire Breakpoint Change events when breakpoints are set.
                // Instead it sends a new breakpoint event when it is bound (after configuration done).
                bool bindsLate = (settings.DebuggerSettings.DebuggerType == SupportedDebugger.VsDbg);

                this.Comment("Set a breakpoint on line 8, but expect it to resolve to line 9.");
                runner.Expects.ConditionalEvent(!bindsLate, x => x.BreakpointChangedEvent(BreakpointReason.Changed, 9))
                .AfterSetBreakpoints(debuggee.Breakpoints(HelloSourceName, 8));

                this.Comment("Start debuggging until breakpoint is hit.");
                runner.Expects.ConditionalEvent(bindsLate, x => x.BreakpointChangedEvent(BreakpointReason.Changed, 9))
                .Event(stopAtBreak)
                .AfterConfigurationDone();

                Assert.Equal(HelloSourceName, stopAtBreak.ActualEventInfo.Filename);
                Assert.Equal(9, stopAtBreak.ActualEventInfo.Line);
                Assert.Equal(StoppedReason.Breakpoint, stopAtBreak.ActualEventInfo.Reason);

                this.Comment("Step forward twice until we have initialized variables");
                runner.Expects.StoppedEvent(StoppedReason.Step, HelloSourceName, 10)
                .AfterStepOver();
                runner.Expects.StoppedEvent(StoppedReason.Step, HelloSourceName, 11)
                .AfterStepIn();

                this.Comment("Inspect the stack and try evaluation.");
                using (IThreadInspector inspector = runner.GetThreadInspector())
                {
                    this.Comment("Get the stack trace");
                    IFrameInspector mainFrame = inspector.Stack.First();
                    inspector.AssertStackFrameNames(true, "main.*");

                    this.WriteLine("Main frame: {0}", mainFrame);

                    this.Comment("Get variables");
                    Assert.Subset(new HashSet <string>()
                    {
                        "x", "y", "argc", "argv"
                    }, mainFrame.Variables.ToKeySet());
                    mainFrame.AssertVariables(
                        "x", "6",
                        "argc", "1");

                    IVariableInspector argv = mainFrame.Variables["argv"];
                    Assert.Matches(HexNumberPattern, argv.Value);

                    this.Comment("Expand a variable (argv has *argv under it)");
                    string variableName = "*argv";
                    if (settings.DebuggerSettings.DebuggerType == SupportedDebugger.VsDbg)
                    {
                        variableName = String.Empty;
                    }
                    Assert.Contains(variableName, argv.Variables.Keys);
                    Assert.Matches(HexNumberPattern, argv.Variables[variableName].Value);

                    this.Comment("Evaluate with side effect");
                    string result = mainFrame.Evaluate("x = x + 1");
                    Assert.Equal("7", result);
                }

                this.Comment("Step to force stack info to refresh");
                runner.Expects.StoppedEvent(StoppedReason.Step).AfterStepOver();

                using (IThreadInspector inspector = runner.GetThreadInspector())
                {
                    this.Comment("Evaluation has side effect, make sure it propagates");
                    Assert.Equal("7", inspector.Stack.First().Variables["x"].Value);
                }

                runner.Expects.ExitedEvent(0).TerminatedEvent().AfterContinue();
                runner.DisconnectAndVerify();
            }
        }