// This method evaluates the expression synchronously. int IDebugExpression2.EvaluateSync(enum_EVALFLAGS dwFlags, uint dwTimeout, IDebugEventCallback2 pExprCallback, out IDebugProperty2 ppResult) { AutoResetEvent completion = new AutoResetEvent(false); PythonEvaluationResult result = null; TaskHelpers.RunSynchronouslyOnUIThread(ct => _frame.StackFrame.ExecuteTextAsync(_expression, (obj) => { result = obj; completion.Set(); }, ct)); while (!_frame.StackFrame.Thread.Process.HasExited && !completion.WaitOne(Math.Min((int)dwTimeout, 100))) { if (dwTimeout <= 100) { break; } dwTimeout -= 100; } if (_frame.StackFrame.Thread.Process.HasExited || result == null) { ppResult = null; return(VSConstants.E_FAIL); } else if (result == null) { ppResult = null; return(DebuggerConstants.E_EVALUATE_TIMEOUT); } ppResult = new AD7Property(_frame, result, _writable); return(VSConstants.S_OK); }
private void EvalTest(string filename, int lineNo, string frameName, int frameIndex, EvalResult eval) { var debugger = new PythonDebugger(); PythonThread thread = null; var process = DebugProcess(debugger, DebuggerTestPath + filename, (newproc, newthread) => { var breakPoint = newproc.AddBreakPoint(filename, lineNo); breakPoint.Add(); thread = newthread; }); AutoResetEvent brkHit = new AutoResetEvent(false); process.BreakpointHit += (sender, args) => { brkHit.Set(); }; process.ExceptionRaised += (sender, args) => { args.Thread.Resume(); }; process.Start(); brkHit.WaitOne(); var frames = thread.GetFrames(); PythonEvaluationResult obj = null; string errorMsg; if (eval.IsError) { Assert.IsTrue(!frames[frameIndex].TryParseText(eval.Expression, out errorMsg)); Assert.AreEqual(errorMsg, eval.ExceptionText); } else { Assert.IsTrue(frames[frameIndex].TryParseText(eval.Expression, out errorMsg)); Assert.AreEqual(errorMsg, null); AutoResetEvent textExecuted = new AutoResetEvent(false); Assert.AreEqual(frameName, frames[frameIndex].FunctionName); frames[frameIndex].ExecuteText(eval.Expression, (completion) => { obj = completion; textExecuted.Set(); } ); textExecuted.WaitOne(); eval.Validate(obj); } process.Continue(); process.WaitForExit(); }
public void Validate(PythonEvaluationResult result) { if (ExceptionText != null) { Assert.AreEqual(result.ExceptionText, ExceptionText); } else { Assert.AreEqual(result.TypeName, _typeName); Assert.AreEqual(result.StringRepr, _repr); } }
public void Validate(PythonEvaluationResult result) { if (ExceptionText != null) { Assert.AreEqual(ExceptionText, result.ExceptionText); } else { if (_typeName != null) { Assert.AreEqual(_typeName, result.TypeName); } if (ValidateRepr) { Assert.AreEqual(_repr, result.StringRepr); } if (ValidateHexRepr) { Assert.AreEqual(HexRepr, result.HexRepr); } if (_length != null) { Assert.AreEqual(_length.Value, result.Length); } if (_flags != null) { if (_allowOtherFlags) { Assert.AreEqual(_flags.Value, _flags.Value & result.Flags); } else { Assert.AreEqual(_flags.Value, result.Flags); } } } }
private async Task <CompletionResult[]> GetMemberNamesAsync(string text) { // TODO: implement support for getting members for module scope, // not just for current frame scope if (_currentScopeName == CurrentFrameScopeFixedName) { var frame = GetFrames().SingleOrDefault(f => f.FrameId == _frameId); if (frame != null) { using (var completion = new AutoResetEvent(false)) { PythonEvaluationResult result = null; var expression = string.Format(CultureInfo.InvariantCulture, "':'.join(dir({0}))", text ?? ""); _serviceProvider.GetUIThread().InvokeTaskSync(() => frame.ExecuteTextAsync(expression, PythonEvaluationResultReprKind.Raw, (obj) => { result = obj; try { completion.Set(); } catch (ObjectDisposedException) { } }, CancellationToken.None), CancellationToken.None); if (completion.WaitOne(100) && !_process.HasExited && result?.StringRepr != null) { // We don't really know if it's a field, function or else... var completionResults = result.StringRepr .Split(':') .Where(r => !string.IsNullOrEmpty(r)) .Select(r => new CompletionResult(r, Interpreter.PythonMemberType.Field)) .ToArray(); return(completionResults); } } } } return(Array.Empty <CompletionResult>()); }
public AD7Property(AD7StackFrame frame, PythonEvaluationResult obj, bool writable = false) { _evalResult = obj; _frame = frame; _writable = writable; }
private DkmEvaluationResult GetPythonView(DkmVisualizedExpression visualizedExpression) { var stackFrame = visualizedExpression.StackFrame; var process = stackFrame.Process; var pythonRuntime = process.GetPythonRuntimeInstance(); if (pythonRuntime == null) { return(null); } var home = visualizedExpression.ValueHome as DkmPointerValueHome; if (home == null) { Debug.Fail("PythonViewNativeVisualizer given a visualized expression that has a non-DkmPointerValueHome home."); return(null); } else if (home.Address == 0) { return(null); } var exprEval = process.GetDataItem <ExpressionEvaluator>(); if (exprEval == null) { Debug.Fail("PythonViewNativeVisualizer failed to obtain an instance of ExpressionEvaluator."); return(null); } string cppTypeName = null; var childExpr = visualizedExpression as DkmChildVisualizedExpression; if (childExpr != null) { var evalResult = childExpr.EvaluationResult as DkmSuccessEvaluationResult; cppTypeName = evalResult.Type; } else { object punkTypeSymbol; visualizedExpression.GetSymbolInterface(typeof(IDiaSymbol).GUID, out punkTypeSymbol); using (ComPtr.Create(punkTypeSymbol)) { var typeSymbol = punkTypeSymbol as IDiaSymbol; if (typeSymbol != null) { cppTypeName = typeSymbol.name; } } } PyObject objRef; try { objRef = PyObject.FromAddress(process, home.Address); } catch { return(null); } // TODO: Localization - [Python view] also appears in .natvis file, leave as-is for now var pyEvalResult = new PythonEvaluationResult(objRef, "[Python view]") { Category = DkmEvaluationResultCategory.Property, AccessType = DkmEvaluationResultAccessType.Private }; var inspectionContext = visualizedExpression.InspectionContext; CppExpressionEvaluator cppEval; try { cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame); } catch { return(null); } var pythonContext = DkmInspectionContext.Create(visualizedExpression.InspectionSession, pythonRuntime, stackFrame.Thread, inspectionContext.Timeout, inspectionContext.EvaluationFlags, inspectionContext.FuncEvalFlags, inspectionContext.Radix, DkmLanguage.Create("Python", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.PythonLanguageGuid)), null); try { return(exprEval.CreatePyObjectEvaluationResult(pythonContext, stackFrame, null, pyEvalResult, cppEval, cppTypeName, hasCppView: true)); } catch { return(null); } }
private DkmEvaluationResult GetPythonView(DkmVisualizedExpression visualizedExpression) { var stackFrame = visualizedExpression.StackFrame; var process = stackFrame.Process; var pythonRuntime = process.GetPythonRuntimeInstance(); if (pythonRuntime == null) { return null; } var home = visualizedExpression.ValueHome as DkmPointerValueHome; if (home == null) { Debug.Fail("PythonViewNativeVisualizer given a visualized expression that has a non-DkmPointerValueHome home."); return null; } else if (home.Address == 0) { return null; } var exprEval = process.GetDataItem<ExpressionEvaluator>(); if (exprEval == null) { Debug.Fail("PythonViewNativeVisualizer failed to obtain an instance of ExpressionEvaluator."); return null; } string cppTypeName = null; var childExpr = visualizedExpression as DkmChildVisualizedExpression; if (childExpr != null) { var evalResult = childExpr.EvaluationResult as DkmSuccessEvaluationResult; cppTypeName = evalResult.Type; } else { object punkTypeSymbol; visualizedExpression.GetSymbolInterface(typeof(IDiaSymbol).GUID, out punkTypeSymbol); using (ComPtr.Create(punkTypeSymbol)) { var typeSymbol = punkTypeSymbol as IDiaSymbol; if (typeSymbol != null) { cppTypeName = typeSymbol.name; } } } PyObject objRef; try { objRef = PyObject.FromAddress(process, home.Address); } catch { return null; } var pyEvalResult = new PythonEvaluationResult(objRef, "[Python view]") { Category = DkmEvaluationResultCategory.Property, AccessType = DkmEvaluationResultAccessType.Private }; var inspectionContext = visualizedExpression.InspectionContext; CppExpressionEvaluator cppEval; try { cppEval = new CppExpressionEvaluator(inspectionContext, stackFrame); } catch { return null; } var pythonContext = DkmInspectionContext.Create(visualizedExpression.InspectionSession, pythonRuntime, stackFrame.Thread, inspectionContext.Timeout, inspectionContext.EvaluationFlags, inspectionContext.FuncEvalFlags, inspectionContext.Radix, DkmLanguage.Create("Python", new DkmCompilerId(Guids.MicrosoftVendorGuid, Guids.PythonLanguageGuid)), null); try { return exprEval.CreatePyObjectEvaluationResult(pythonContext, stackFrame, null, pyEvalResult, cppEval, cppTypeName, hasCppView: true); } catch { return null; } }
private void ChildTest(string filename, int lineNo, string text, params ChildInfo[] children) { var debugger = new PythonDebugger(); PythonThread thread = null; var process = DebugProcess(debugger, DebuggerTestPath + filename, (newproc, newthread) => { var breakPoint = newproc.AddBreakPoint(filename, lineNo); breakPoint.Add(); thread = newthread; }); AutoResetEvent brkHit = new AutoResetEvent(false); process.BreakpointHit += (sender, args) => { brkHit.Set(); }; process.ExceptionRaised += (sender, args) => { // some versions of Python raise exceptions during startup args.Thread.Resume(); }; process.Start(); brkHit.WaitOne(); var frames = thread.GetFrames(); AutoResetEvent evalComplete = new AutoResetEvent(false); PythonEvaluationResult evalRes = null; frames[0].ExecuteText(text, (completion) => { evalRes = completion; evalComplete.Set(); }); evalComplete.WaitOne(); Assert.IsTrue(evalRes != null); if (children == null) { Assert.IsTrue(!evalRes.IsExpandable); Assert.IsTrue(evalRes.GetChildren(Int32.MaxValue) == null); } else { Assert.IsTrue(evalRes.IsExpandable); var childrenReceived = new List <PythonEvaluationResult>(evalRes.GetChildren(Int32.MaxValue)); Assert.IsTrue(children.Length == childrenReceived.Count); for (int i = 0; i < children.Length; i++) { bool foundChild = false; for (int j = 0; j < childrenReceived.Count; j++) { if (childrenReceived[j].ChildText == children[i].ChildText && childrenReceived[j].StringRepr == children[i].Repr) { foundChild = true; if (children[i].ChildText.StartsWith("[")) { Assert.AreEqual(childrenReceived[j].Expression, text + children[i].ChildText); } else { Assert.AreEqual(childrenReceived[j].Expression, text + "." + children[i].ChildText); } Assert.AreEqual(childrenReceived[j].Frame, frames[0]); childrenReceived.RemoveAt(j); break; } } Assert.IsTrue(foundChild); } Assert.IsTrue(childrenReceived.Count == 0); } process.Continue(); process.WaitForExit(); }