protected override void HandleScopesRequestAsync(IRequestResponder <ScopesArguments, ScopesResponse> responder) { // Create our scope list List <Scope> scopeList = new List <Scope>(); // Obtain all relevant ids. int stackFrameId = responder.Arguments.FrameId; int?localScopeId = ReferenceContainer.GetLocalScopeId(stackFrameId); int?stateScopeId = ReferenceContainer.GetStateScopeId(stackFrameId); // Add state variable scope if applicable. if (stateScopeId.HasValue) { scopeList.Add(new Scope("State Variables", stateScopeId.Value, false)); } // Add local variable scope if applicable. if (localScopeId.HasValue) { scopeList.Add(new Scope("Local Variables", localScopeId.Value, false)); } // Set our response. responder.SetResponse(new ScopesResponse(scopeList)); }
protected override void HandleThreadsRequestAsync(IRequestResponder <ThreadsArguments, ThreadsResponse> responder) { // Create a list of threads from our thread states. List <Thread> threads = ThreadStates.Values.Select(x => new Thread(x.ThreadId, $"thread_{x.ThreadId}")).ToList(); responder.SetResponse(new ThreadsResponse(threads)); }
protected override void HandleSetBreakpointsRequestAsync(IRequestResponder <SetBreakpointsArguments, SetBreakpointsResponse> responder) { // Ignore breakpoints for files that are not solidity sources if (!responder.Arguments.Source.Path.EndsWith(".sol", StringComparison.OrdinalIgnoreCase)) { responder.SetResponse(new SetBreakpointsResponse()); return; } if (!responder.Arguments.Source.Path.StartsWith(ConfigurationProperties.WorkspaceDirectory, StringComparison.OrdinalIgnoreCase)) { throw new Exception($"Unexpected breakpoint source path: {responder.Arguments.Source.Path}, workspace: {ConfigurationProperties.WorkspaceDirectory}"); } if (responder.Arguments.SourceModified.GetValueOrDefault()) { throw new Exception("Debugging modified sources is not supported."); } // Obtain our internal path from a vs code path var relativeFilePath = ConvertVSCodePathToInternalPath(responder.Arguments.Source.Path); _sourceBreakpoints[relativeFilePath] = responder.Arguments.Breakpoints.Select(b => b.Line).ToArray(); responder.SetResponse(new SetBreakpointsResponse()); }
protected override void HandleDisconnectRequestAsync(IRequestResponder <DisconnectArguments> responder) { responder.SetResponse(new DisconnectResponse()); Protocol.SendEvent(new TerminatedEvent()); Protocol.SendEvent(new ExitedEvent(0)); _terminatedTcs.TrySetResult(null); }
protected override void HandleLaunchRequestAsync(IRequestResponder <LaunchArguments> responder) { if (session != null) { var ex = new InvalidOperationException(); Log(ex.Message, LogCategory.DebugAdapterOutput); responder.SetError(new ProtocolException(ex.Message, ex)); return; } _ = LaunchConfigParser.CreateDebugSessionAsync(responder.Arguments, Protocol.SendEvent, defaultDebugView) .ContinueWith(t => { if (t.IsCompletedSuccessfully) { session = t.Result; session.Start(); Protocol.SendEvent(new InitializedEvent()); responder.SetResponse(new LaunchResponse()); } else { if (t.Exception != null) { responder.SetError(new ProtocolException(t.Exception.Message, t.Exception)); } else { responder.SetError(new ProtocolException($"Unknown error in {nameof(LaunchConfigParser.CreateDebugSessionAsync)}")); } } }, TaskScheduler.Current); }
protected override void HandleSetExceptionBreakpointsRequestAsync(IRequestResponder <SetExceptionBreakpointsArguments> responder) { lock (_exceptionBreakpointFilters) { _exceptionBreakpointFilters = new HashSet <string>(responder.Arguments.Filters); var response = new SetExceptionBreakpointsResponse(); responder.SetResponse(response); } }
protected override void HandleVariablesRequestAsync(IRequestResponder <VariablesArguments, VariablesResponse> responder) { // Obtain relevant variable resolving information. int threadId = 0; int traceIndex = 0; bool isLocalVariableScope = false; bool isStateVariableScope = false; bool isParentVariableScope = false; UnderlyingVariableValuePair parentVariableValuePair = new UnderlyingVariableValuePair(null, null); // Try to obtain the variable reference as a local variable scope. isLocalVariableScope = ReferenceContainer.ResolveLocalVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex); if (!isLocalVariableScope) { // Try to obtain the variable reference as a state variable scope. isStateVariableScope = ReferenceContainer.ResolveStateVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex); if (!isStateVariableScope) { // Try to obtain the variable reference as a sub-variable scope. isParentVariableScope = ReferenceContainer.ResolveParentVariable(responder.Arguments.VariablesReference, out threadId, out parentVariableValuePair); } } // Using our thread id, obtain our thread state ThreadStates.TryGetValue(threadId, out var threadState); // Verify the thread state is valid if (threadState == null) { responder.SetResponse(new VariablesResponse()); return; } // Obtain the trace index for this scope. List <Variable> variableList = new List <Variable>(); try { ResolveVariables( variableList, responder.Arguments.VariablesReference, isLocalVariableScope, isStateVariableScope, isParentVariableScope, traceIndex, parentVariableValuePair, threadState); } catch (Exception ex) { LogException(ex, threadState); } // Respond with our variable list. responder.SetResponse(new VariablesResponse(variableList)); }
protected ServiceBase( IRequestResponder requestResponder, ICommandListener commandListener, IEndpointDetailsProvider endpointDetailsProvider) { _requestResponder = requestResponder; _commandListener = commandListener; _endpointDetailsProvider = endpointDetailsProvider; _subscriptions = new List <IDisposable>(); }
protected override void HandleExceptionInfoRequestAsync(IRequestResponder <ExceptionInfoArguments, ExceptionInfoResponse> responder) { // Obtain the current thread state bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState); if (success) { string exceptionMessage = threadState.ExecutionTraceAnalysis.GetException(threadState.CurrentStepIndex.Value).Message; responder.SetResponse(new ExceptionInfoResponse(exceptionMessage, ExceptionBreakMode.Always)); } }
protected override void HandleStepBackRequestAsync(IRequestResponder <StepBackArguments> responder) { // Set our response responder.SetResponse(new StepBackResponse()); // Obtain the current thread state bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState); if (success) { // Continue executing ContinueExecution(threadState, DesiredControlFlow.StepBackwards); } }
protected override void HandleEvaluateRequestAsync(IRequestResponder <EvaluateArguments, EvaluateResponse> responder) { EvaluateResponse evalResponse = null; if (responder.Arguments.Expression.StartsWith(VARIABLE_EVAL_TYPE, StringComparison.Ordinal)) { var id = int.Parse(responder.Arguments.Expression.Substring(VARIABLE_EVAL_TYPE.Length), CultureInfo.InvariantCulture); if (_variableEvaluationValues.TryGetValue(id, out var evalResult)) { evalResponse = new EvaluateResponse { Result = evalResult }; } } responder.SetResponse(evalResponse ?? new EvaluateResponse()); }
protected override void HandleContinueRequestAsync(IRequestResponder <ContinueArguments, ContinueResponse> responder) { // Set our response responder.SetResponse(new ContinueResponse()); // Obtain the current thread state bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState); if (success) { // Advance our step from our current position threadState.IncrementStep(); // Continue executing ContinueExecution(threadState, DesiredControlFlow.Continue); } }
protected override void HandleContinueRequestAsync(IRequestResponder <ContinueArguments, ContinueResponse> responder) { // Set our response responder.SetResponse(new ContinueResponse()); // Obtain the current thread state bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState); if (success) { // Continue executing, taking one step before continuing, as evaluation occurs before steps occur, and we want // to ensure we advanced position from our last and don't re-evaluate the same trace point. We only do this on // startup since we want the initial trace point to be evaluated. After that, we want to force advancement by // at least one step before continuation/re-evaluation. ContinueExecution(threadState, DesiredControlFlow.Continue, 1); } }
protected override void HandleInitializeRequestAsync(IRequestResponder <InitializeArguments, InitializeResponse> responder) { var response = new InitializeResponse { SupportsConfigurationDoneRequest = true, SupportsEvaluateForHovers = true, SupportsStepBack = true, SupportsStepInTargetsRequest = true, SupportTerminateDebuggee = false, SupportsRestartRequest = false, SupportsRestartFrame = false, SupportedChecksumAlgorithms = new List <ChecksumAlgorithm> { ChecksumAlgorithm.SHA256 } }; responder.SetResponse(response); Protocol.SendEvent(new InitializedEvent()); CompletedInitializationRequest.SetResult(null); }
private void OnPromptRequest(IRequestResponder <PromptArgs, PromptResponse> responder) { IVsUIShell shell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell; try { this.context.Logger.Log("Responding to 'prompt' request."); shell.EnableModeless(0); DialogResult result = MessageBox.Show(responder.Arguments.Message, "Prompt from Debug Adapter", MessageBoxButtons.OKCancel); responder.SetResponse( new PromptResponse() { Response = result == DialogResult.OK ? PromptResponse.ResponseValue.OK : PromptResponse.ResponseValue.Cancel }); } finally { shell.EnableModeless(1); } }
protected override void HandleInitializeRequestAsync(IRequestResponder <InitializeArguments, InitializeResponse> responder) { var response = new InitializeResponse { SupportsConfigurationDoneRequest = true, SupportsEvaluateForHovers = true, SupportsStepBack = true, SupportsStepInTargetsRequest = true, SupportTerminateDebuggee = false, SupportsRestartRequest = false, SupportsRestartFrame = false, SupportedChecksumAlgorithms = new List <ChecksumAlgorithm> { ChecksumAlgorithm.SHA256 }, SupportsExceptionInfoRequest = true }; response.ExceptionBreakpointFilters = new List <ExceptionBreakpointsFilter> { new ExceptionBreakpointsFilter { Filter = EXCEPTION_BREAKPOINT_FILTER_ALL, Label = EXCEPTION_BREAKPOINT_FILTER_ALL, Default = false }, new ExceptionBreakpointsFilter { Filter = EXCEPTION_BREAKPOINT_FILTER_UNHANDLED, Label = EXCEPTION_BREAKPOINT_FILTER_UNHANDLED, Default = true } }; responder.SetResponse(response); Protocol.SendEvent(new InitializedEvent()); CompletedInitializationRequest.SetResult(null); }
protected override void HandleExceptionInfoRequestAsync(IRequestResponder <ExceptionInfoArguments, ExceptionInfoResponse> responder) { // Obtain the current thread state bool success = ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState); if (success) { var ex = threadState.ExecutionTraceAnalysis.GetException(threadState.CurrentStepIndex.Value); // Get the exception call stack lines. var exStackTrace = threadState.ExecutionTraceAnalysis.GetCallStackString(ex.TraceIndex.Value); responder.SetResponse(new ExceptionInfoResponse("Error", ExceptionBreakMode.Always) { Description = ex.Message, Details = new ExceptionDetails { Message = ex.Message, FormattedDescription = ex.Message, StackTrace = exStackTrace } }); } }
protected override void HandleDisconnectRequestAsync(IRequestResponder <DisconnectArguments> responder) { // Set our exiting status Exiting = true; // Loop for each thread foreach (var threadStateKeyValuePair in ThreadStates) { // Release the execution lock on this thread state. // NOTE: This already happens when setting exiting status, // but only if the thread is currently stepping/continuing, // and not paused. This will allow it to continue if stopped. threadStateKeyValuePair.Value.Semaphore.Release(); } // Set our response to the disconnect request. responder.SetResponse(new DisconnectResponse()); Protocol.SendEvent(new TerminatedEvent()); Protocol.SendEvent(new ExitedEvent(0)); _terminatedTcs.TrySetResult(null); // If we have an event, invoke it OnDebuggerDisconnect?.Invoke(this); }
/* * protected override ResponseBody HandleProtocolRequest(string requestType, object requestArgs) * { * return base.HandleProtocolRequest(requestType, requestArgs); * }*/ protected override void HandleRestartRequestAsync(IRequestResponder <RestartArguments> responder) { base.HandleRestartRequestAsync(responder); }
protected override void HandleLoadedSourcesRequestAsync(IRequestResponder <LoadedSourcesArguments, LoadedSourcesResponse> responder) { base.HandleLoadedSourcesRequestAsync(responder); }
protected override void HandleSetDebuggerPropertyRequestAsync(IRequestResponder <SetDebuggerPropertyArguments> responder) { base.HandleSetDebuggerPropertyRequestAsync(responder); }
protected override void HandleEvaluateRequestAsync(IRequestResponder <EvaluateArguments, EvaluateResponse> responder) { responder.SetResponse(new EvaluateResponse()); }
protected override void HandleVariablesRequestAsync(IRequestResponder <VariablesArguments, VariablesResponse> responder) { // Obtain relevant variable resolving information. int threadId = 0; int traceIndex = 0; bool isLocalVariableScope = false; bool isStateVariableScope = false; bool isParentVariableScope = false; UnderlyingVariableValuePair parentVariableValuePair = new UnderlyingVariableValuePair(null, null); // Try to obtain the variable reference as a local variable scope. isLocalVariableScope = ReferenceContainer.ResolveLocalVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex); if (!isLocalVariableScope) { // Try to obtain the variable reference as a state variable scope. isStateVariableScope = ReferenceContainer.ResolveStateVariable(responder.Arguments.VariablesReference, out threadId, out traceIndex); if (!isStateVariableScope) { // Try to obtain the variable reference as a sub-variable scope. isParentVariableScope = ReferenceContainer.ResolveParentVariable(responder.Arguments.VariablesReference, out threadId, out parentVariableValuePair); } } // Using our thread id, obtain our thread state ThreadStates.TryGetValue(threadId, out var threadState); // Verify the thread state is valid if (threadState == null) { responder.SetResponse(new VariablesResponse()); return; } // Obtain the trace index for this scope. List <Variable> variableList = new List <Variable>(); // Obtain our local variables at this point in execution VariableValuePair[] variablePairs = Array.Empty <VariableValuePair>(); if (isLocalVariableScope) { variablePairs = threadState.ExecutionTraceAnalysis.GetLocalVariables(traceIndex); } else if (isStateVariableScope) { variablePairs = threadState.ExecutionTraceAnalysis.GetStateVariables(traceIndex); } else if (isParentVariableScope) { // We're loading sub-variables for a variable. switch (parentVariableValuePair.Variable.GenericType) { case VarGenericType.Struct: { // Cast our to an enumerable type. variablePairs = ((IEnumerable <VariableValuePair>)parentVariableValuePair.Value).ToArray(); break; } case VarGenericType.Array: { // Cast our variable var arrayVariable = ((VarArray)parentVariableValuePair.Variable); // Cast to an object array. var arrayValue = (object[])parentVariableValuePair.Value; // Loop for each element for (int i = 0; i < arrayValue.Length; i++) { // Create an underlying variable value pair for this element var underlyingVariableValuePair = new UnderlyingVariableValuePair(arrayVariable.ElementObject, arrayValue[i]); // Check if this is a nested variable type bool nestedType = IsNestedVariableType(arrayVariable.ElementObject.GenericType); int variablePairReferenceId = 0; if (nestedType) { // Create a new reference id for this variable if it's a nested type. variablePairReferenceId = ReferenceContainer.GetUniqueId(); // Link our reference for any nested types. ReferenceContainer.LinkSubVariableReference(responder.Arguments.VariablesReference, variablePairReferenceId, threadId, underlyingVariableValuePair); } // Obtain the value string for this variable and add it to our list. string variableValueString = GetVariableValueString(underlyingVariableValuePair); variableList.Add(new Variable($"[{i}]", variableValueString, variablePairReferenceId)); } break; } case VarGenericType.ByteArrayDynamic: case VarGenericType.ByteArrayFixed: { // Cast our to an enumerable type. var bytes = (Memory <byte>)parentVariableValuePair.Value; for (int i = 0; i < bytes.Length; i++) { variableList.Add(new Variable($"[{i}]", bytes.Span[i].ToString(CultureInfo.InvariantCulture), 0)); } break; } } } // Loop for each local variables foreach (VariableValuePair variablePair in variablePairs) { // Create an underlying variable value pair for this pair. var underlyingVariableValuePair = new UnderlyingVariableValuePair(variablePair); // Check if this is a nested variable type bool nestedType = IsNestedVariableType(variablePair.Variable.GenericType); int variablePairReferenceId = 0; if (nestedType) { // Create a new reference id for this variable if it's a nested type. variablePairReferenceId = ReferenceContainer.GetUniqueId(); // Link our reference for any nested types. ReferenceContainer.LinkSubVariableReference(responder.Arguments.VariablesReference, variablePairReferenceId, threadId, underlyingVariableValuePair); } // Obtain the value string for this variable and add it to our list. string variableValueString = GetVariableValueString(underlyingVariableValuePair); variableList.Add(new Variable(variablePair.Variable.Name, variableValueString, variablePairReferenceId)); } // Respond with our variable list. responder.SetResponse(new VariablesResponse(variableList)); }
protected override void HandleStackTraceRequestAsync(IRequestResponder <StackTraceArguments, StackTraceResponse> responder) { // Create a list of stack frames or try to get cached ones. List <StackFrame> stackFrames; bool cachedStackFrames = ReferenceContainer.TryGetStackFrames(responder.Arguments.ThreadId, out stackFrames); // Verify we have a thread state for this thread, and a valid step to represent in it. if (!cachedStackFrames && ThreadStates.TryGetValue(responder.Arguments.ThreadId, out var threadState) && threadState.CurrentStepIndex.HasValue) { // Initialize our stack frame list stackFrames = new List <StackFrame>(); // Obtain the callstack var callstack = threadState.ExecutionTraceAnalysis.GetCallStack(threadState.CurrentStepIndex.Value); // Loop through our scopes. for (int i = 0; i < callstack.Length; i++) { // Grab our current call frame var currentStackFrame = callstack[i]; // If the scope could not be resolved within a function, and no lines could be resolved, skip to the next frame. // as this is not a code section we can describe in any meaningful way. if (!currentStackFrame.ResolvedFunction && currentStackFrame.CurrentPositionLines.Length == 0) { continue; } // If we couldn't resolve the current position or there were no lines representing it if (currentStackFrame.Error || currentStackFrame.CurrentPositionLines.Length == 0) { continue; } // Obtain the method name we are executing in. string frameName = currentStackFrame.FunctionName; if (string.IsNullOrEmpty(frameName)) { frameName = "<undefined>"; } // Determine the bounds of our stack frame. int startLine = 0; int startColumn = 0; int endLine = 0; int endColumn = 0; // Loop through all of our lines for this position. for (int x = 0; x < currentStackFrame.CurrentPositionLines.Length; x++) { // Obtain our indexed line. SourceFileLine line = currentStackFrame.CurrentPositionLines[x]; // Set our start position if relevant. if (x == 0 || line.LineNumber <= startLine) { // Set our starting line number. startLine = line.LineNumber; // TODO: Determine our column start } // Set our end position if relevant. if (x == 0 || line.LineNumber >= endLine) { // Set our ending line number. endLine = line.LineNumber; // TODO: Determine our column endColumn = line.Length; } } // Format agnostic path to platform specific path var sourceFilePath = currentStackFrame.CurrentPositionLines[0].SourceFileMapParent.SourceFilePath; if (Path.DirectorySeparatorChar == '\\') { sourceFilePath = sourceFilePath.Replace('/', Path.DirectorySeparatorChar); } // Create our source object Source stackFrameSource = new Source() { Name = currentStackFrame.CurrentPositionLines[0].SourceFileMapParent.SourceFileName, Path = Path.Join(ConfigurationProperties.WorkspaceDirectory, _contractsDirectory, sourceFilePath) }; var stackFrame = new StackFrame() { Id = ReferenceContainer.GetUniqueId(), Name = frameName, Line = startLine, Column = startColumn, Source = stackFrameSource, EndLine = endLine, EndColumn = endColumn }; // Add the stack frame to our reference list ReferenceContainer.LinkStackFrame(threadState.ThreadId, stackFrame, currentStackFrame.CurrentPositionTraceIndex); // Add our stack frame to the result list stackFrames.Add(stackFrame); } } // Return our stack frames in our response. responder.SetResponse(new StackTraceResponse(stackFrames)); }
protected override void HandleSetVariableRequestAsync(IRequestResponder <SetVariableArguments, SetVariableResponse> responder) { throw new NotImplementedException(); }
protected override void HandleTerminateThreadsRequestAsync(IRequestResponder <TerminateThreadsArguments> responder) { base.HandleTerminateThreadsRequestAsync(responder); }
protected override void HandleSourceRequestAsync(IRequestResponder <SourceArguments, SourceResponse> responder) { base.HandleSourceRequestAsync(responder); }
protected override void HandleReverseContinueRequestAsync(IRequestResponder <ReverseContinueArguments> responder) { base.HandleReverseContinueRequestAsync(responder); }
protected override void HandleVariablesRequestAsync(IRequestResponder <VariablesArguments, VariablesResponse> responder) { responder.SetResponse( new VariablesResponse( GetVariables(responder.Arguments.VariablesReference))); }
protected override void HandlePauseRequestAsync(IRequestResponder <PauseArguments> responder) { responder.SetResponse(new PauseResponse()); }