public bool Assign(string expression, out string error) { if (IsReadOnly) { error = string.Format( "Attempted to assign a value to a read only variable with name '{0}'.", DisplayName); return(false); } string cast = ""; if (_remoteValue.TypeIsPointerType() || _remoteValue.GetTypeInfo().GetTypeFlags().HasFlag(TypeFlags.IS_ENUMERATION)) { cast = $"({_remoteValue.GetTypeInfo().GetCanonicalType().GetName()})"; } expression = _remoteValueFormat.FormatExpressionForAssignment(_remoteValue, expression); // Avoid using parentheses to enclose registers because they can prevent assignments // involving initialization lists from succeeding. if (_remoteValue.GetValueType() != DebuggerApi.ValueType.Register) { expression = $"({expression})"; } RemoteValue tempValue = _remoteValue.CreateValueFromExpression( DisplayName, $"{_remoteValue.GetVariableAssignExpression()} = {cast}{expression}"); SbError sbError = tempValue.GetError(); error = sbError.Fail() ? sbError.GetCString() : null; return(sbError.Success()); }
public bool ApplyPlaceholderProperties(SbModule destModule, PlaceholderModuleProperties properties, RemoteTarget lldbTarget) { long slide = properties.Slide; SbAddress headerAddress = destModule.GetObjectFileHeaderAddress(); if (headerAddress != null) { // For libraries this will generally equal 0, for executables it will equal // |placeholderBaseLoadAddress|. ulong fileBaseAddress = headerAddress.GetFileAddress(); slide -= (long)fileBaseAddress; } SbError error = lldbTarget.SetModuleLoadAddress(destModule, slide); if (error.Fail()) { Trace.WriteLine( $"Failed to set load address on destination module: {error.GetCString()}."); return(false); } if (!destModule.SetPlatformFileSpec(properties.PlatformFileSpec)) { Trace.WriteLine("Failed to set file spec on the destination module."); return(false); } return(true); }
internal static GrpcSbError CreateError(SbError error) => error != null ? new GrpcSbError { Success = error.Success(), Code = error.GetError(), Error = error.GetCString() ?? "" } : null;
public override Task <SetModuleLoadAddressResponse> SetModuleLoadAddress( SetModuleLoadAddressRequest request, ServerCallContext context) { RemoteTarget target = GrpcLookupUtils.GetTarget(request.Target, _targetStore); SbModule module = _moduleStore.GetObject(request.Module.Id); SbError error = target.SetModuleLoadAddress(module, request.SectionsOffset); var grpcError = new GrpcSbError { Success = error.Success(), Error = error.GetCString() }; return(Task.FromResult(new SetModuleLoadAddressResponse { Error = grpcError })); }
/// <summary> /// Returns an error string if the _remoteValue's error is in fail state and null otherwise. /// </summary> string GetErrorString() { SbError error = _remoteValue.GetError(); if (!error.Fail()) { return(null); } // TODO: Determine why we are suppressing error strings for REGISTER // ValueTypes. Add comments if needed or remove otherwise. string errorString = _remoteValue.GetValueType() == DebuggerApi.ValueType.Register ? "unavailable" : error.GetCString(); return($"<{errorString}>"); }
/// <summary> /// Get a more detailed error message if attaching to the remote process failed. /// /// At the moment, we handle specially only the case when another tracer is attached. /// In that case, we detect and show which process is the tracer. /// </summary> /// <param name="lldbError">Error object from Lldb attach.</param> /// <param name="platform">Lldb platform, used to run shell commands.</param> /// <param name="processId">Process Id of the debuggee.</param> /// <returns>Returns the error string.</returns> string GetLldbAttachErrorDetails(SbError lldbError, SbPlatform platform, uint processId) { string lldbMessageWhenAlreadyTraced = "Operation not permitted"; // Compute the fallback error message. string errorString = ErrorStrings.FailedToAttachToProcess(lldbError.GetCString()); // If the error does not need special handling, just return the default message. if (platform == null || lldbError.GetCString() != lldbMessageWhenAlreadyTraced) { return(errorString); } // Let us detect if there is a debugger already attached and provide a better error // message there. string output = RunShellCommand($"cat /proc/{processId}/status", platform); if (string.IsNullOrEmpty(output)) { return(errorString); } Regex tracerRE = new Regex("[\\r\\n]TracerPid:\\W*([0-9]+)[\\r\\n]"); Regex parentRE = new Regex("[\\r\\n]PPid:\\W*([0-9]+)[\\r\\n]"); Regex firstLineRE = new Regex("^([^\\r\\n]*)([\\r\\n]|$)"); // Find the line with tracer pid in the proc-status file. Match tracerMatch = tracerRE.Match(output); Match parentMatch = parentRE.Match(output); if (!tracerMatch.Success || !parentMatch.Success) { return(errorString); } string parentPid = parentMatch.Groups[1].Value; string tracerPid = tracerMatch.Groups[1].Value; // If there was no tracer, just show the default message. if (tracerPid == "0") { return(errorString); } // If the tracer is the parent process, then the debuggee is tracing itself. if (tracerPid == parentPid) { return(ErrorStrings.FailedToAttachToProcessSelfTrace); } // Try to find the tracer in the list of processes and report it in the error message. string commOutput = RunShellCommand($"cat /proc/{tracerPid}/comm", platform); if (string.IsNullOrEmpty(output)) { return(errorString); } // Get the first line as the process name. Match commMatch = firstLineRE.Match(commOutput); string tracerName = commMatch.Success ? commMatch.Groups[1].Value : "<unkown>"; return(ErrorStrings.FailedToAttachToProcessOtherTracer(tracerName, tracerPid)); }
public int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext) { int result = CanSetNextStatement(stackFrame, codeContext); if (result != VSConstants.S_OK) { return(VSConstants.E_FAIL); } uint line; string filePath; codeContext.GetDocumentContext(out IDebugDocumentContext2 documentContext); if (documentContext != null) { documentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out filePath); var beginPosition = new TEXT_POSITION[1]; var endPosition = new TEXT_POSITION[1]; documentContext.GetStatementRange(beginPosition, endPosition); line = beginPosition[0].dwLine + 1; Trace.WriteLine($"Settings next statement to {filePath} line {line}."); } else { var process = _remoteThread.GetProcess(); if (process == null) { Trace.WriteLine("Error: Failed to obtain process." + " Unable to set next statement"); return(VSConstants.E_FAIL); } var target = process.GetTarget(); if (target == null) { Trace.WriteLine("Error: Failed to obtain target." + " Unable to set next statement"); return(VSConstants.E_FAIL); } var address = target.ResolveLoadAddress(codeContext.GetAddress()); if (address == null) { Trace.WriteLine("Error: Failed to obtain address." + " Unable to set next statement"); return(VSConstants.E_FAIL); } var lineEntry = address.GetLineEntry(); if (lineEntry == null) { Trace.WriteLine("Error: Failed to obtain line entry." + " Unable to set next statement"); return(VSConstants.E_FAIL); } filePath = Path.Combine(lineEntry.Directory, lineEntry.FileName); line = lineEntry.Line; Trace.WriteLine($"Settings next statement to {address} at {filePath} line {line}"); } SbError error = _remoteThread.JumpToLine(filePath, line); if (error.Fail()) { Trace.WriteLine(error.GetCString()); return(VSConstants.E_FAIL); } return(VSConstants.S_OK); }