Exemplo n.º 1
0
        internal async Task Eval()
        {
            _engine.CurrentRadix();    // ensure the radix value is up-to-date

            string execCommandString = "-exec ";

            if (_strippedName.StartsWith(execCommandString))
            {
                // special case for executing raw mi commands.
                string consoleCommand = _strippedName.Substring(execCommandString.Length);
                string consoleResults = null;

                try
                {
                    consoleResults = await MIDebugCommandDispatcher.ExecuteCommand(consoleCommand);

                    Value         = String.Empty;
                    this.TypeName = null;
                }
                catch (Exception e)
                {
                    if (e.InnerException != null)
                    {
                        e = e.InnerException;
                    }

                    UnexpectedMIResultException miException = e as UnexpectedMIResultException;
                    string message;
                    if (miException != null && miException.MIError != null)
                    {
                        message = miException.MIError;
                    }
                    else
                    {
                        message = e.Message;
                    }

                    SetAsError(string.Format(ResourceStrings.Failed_ExecCommandError, message));
                }

                if (!String.IsNullOrEmpty(consoleResults))
                {
                    _debuggedProcess.WriteOutput(consoleResults);
                }
            }
            else
            {
                int     threadId   = Client.GetDebuggedThread().Id;
                uint    frameLevel = _ctx.Level;
                Results results    = await _engine.DebuggedProcess.MICommandFactory.VarCreate(_strippedName, threadId, frameLevel, ResultClass.None);

                if (results.ResultClass == ResultClass.done)
                {
                    _internalName = results.FindString("name");
                    TypeName      = results.TryFindString("type");
                    if (results.Contains("dynamic") && results.Contains("has_more"))
                    {
                        CountChildren = results.FindUint("has_more");
                    }
                    else
                    {
                        CountChildren = results.FindUint("numchild");
                    }
                    Value = results.TryFindString("value");
                    if ((Value == String.Empty || _format != null) && !string.IsNullOrEmpty(_internalName))
                    {
                        if (_format != null)
                        {
                            await Format();
                        }
                        else
                        {
                            results = await _engine.DebuggedProcess.MICommandFactory.VarEvaluateExpression(_internalName, ResultClass.None);

                            if (results.ResultClass == ResultClass.done)
                            {
                                Value = results.FindString("value");
                            }
                            else if (results.ResultClass == ResultClass.error)
                            {
                                SetAsError(results.FindString("msg"));
                            }
                            else
                            {
                                Debug.Fail("Weird msg from -var-evaluate-expression");
                            }
                        }
                    }
                }
                else if (results.ResultClass == ResultClass.error)
                {
                    SetAsError(results.FindString("msg"));
                }
                else
                {
                    Debug.Fail("Weird msg from -var-create");
                }
            }
        }
Exemplo n.º 2
0
        public DebuggedProcess(bool bLaunched, LaunchOptions launchOptions, ISampleEngineCallback callback, WorkerThread worker, BreakpointManager bpman, AD7Engine engine)
        {
            uint processExitCode = 0;

            g_Process          = this;
            _bStarted          = false;
            _pendingMessages   = new StringBuilder(400);
            _worker            = worker;
            _launchOptions     = launchOptions;
            _breakpointManager = bpman;
            Engine             = engine;
            _libraryLoaded     = new List <string>();
            _loadOrder         = 0;
            MICommandFactory   = MICommandFactory.GetInstance(launchOptions.DebuggerMIMode, this);
            _waitDialog        = MICommandFactory.SupportsStopOnDynamicLibLoad() ? new WaitDialog(ResourceStrings.LoadingSymbolMessage, ResourceStrings.LoadingSymbolCaption) : null;
            Natvis             = new Natvis.Natvis(this);

            // we do NOT have real Win32 process IDs, so we use a guid
            AD_PROCESS_ID pid = new AD_PROCESS_ID();

            pid.ProcessIdType = (int)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            pid.guidProcessId = Guid.NewGuid();
            this.Id           = pid;

            SourceLineCache = new SourceLineCache(this);

            _callback   = callback;
            _moduleList = new List <DebuggedModule>();
            ThreadCache = new ThreadCache(callback, this);
            Disassembly = new Disassembly(this);

            VariablesToDelete = new List <string>();

            MessageEvent += delegate(object o, string message)
            {
                // We can get messages before we have started the process
                // but we can't send them on until it is
                if (_bStarted)
                {
                    _callback.OnOutputString(message);
                }
                else
                {
                    _pendingMessages.Append(message);
                }
            };

            LibraryLoadEvent += delegate(object o, EventArgs args)
            {
                ResultEventArgs results = args as MICore.Debugger.ResultEventArgs;
                string          file    = results.Results.TryFindString("host-name");
                if (!string.IsNullOrEmpty(file) && MICommandFactory.SupportsStopOnDynamicLibLoad())
                {
                    _libraryLoaded.Add(file);
                    if (_waitDialog != null)
                    {
                        _waitDialog.ShowWaitDialog(file);
                    }
                }
                else if (this.MICommandFactory.Mode == MIMode.Clrdbg)
                {
                    string id            = results.Results.FindString("id");
                    ulong  baseAddr      = results.Results.FindAddr("base-address");
                    uint   size          = results.Results.FindUint("size");
                    bool   symbolsLoaded = results.Results.FindInt("symbols-loaded") != 0;
                    var    module        = new DebuggedModule(id, file, baseAddr, size, symbolsLoaded, string.Empty, _loadOrder++);
                    lock (_moduleList)
                    {
                        _moduleList.Add(module);
                    }
                    _callback.OnModuleLoad(module);
                }
                else if (!string.IsNullOrEmpty(file))
                {
                    string addr = results.Results.TryFindString("loaded_addr");
                    if (string.IsNullOrEmpty(addr) || addr == "-")
                    {
                        return; // identifies the exe, not a real load
                    }
                    // generate module
                    string id         = results.Results.TryFindString("name");
                    bool   symsLoaded = true;
                    string symPath    = null;
                    if (results.Results.Contains("symbols-path"))
                    {
                        symPath = results.Results.FindString("symbols-path");
                        if (string.IsNullOrEmpty(symPath))
                        {
                            symsLoaded = false;
                        }
                    }
                    else
                    {
                        symPath = file;
                    }
                    ulong loadAddr = results.Results.FindAddr("loaded_addr");
                    uint  size     = results.Results.FindUint("size");
                    if (String.IsNullOrEmpty(id))
                    {
                        id = file;
                    }
                    var module = FindModule(id);
                    if (module == null)
                    {
                        module = new DebuggedModule(id, file, loadAddr, size, symsLoaded, symPath, _loadOrder++);
                        lock (_moduleList)
                        {
                            _moduleList.Add(module);
                        }
                        _callback.OnModuleLoad(module);
                    }
                }
            };

            if (_launchOptions is LocalLaunchOptions)
            {
                this.Init(new MICore.LocalTransport(), _launchOptions);
            }
            else if (_launchOptions is PipeLaunchOptions)
            {
                this.Init(new MICore.PipeTransport(), _launchOptions);
            }
            else if (_launchOptions is TcpLaunchOptions)
            {
                this.Init(new MICore.TcpTransport(), _launchOptions);
            }
            else if (_launchOptions is SerialLaunchOptions)
            {
                string port = ((SerialLaunchOptions)_launchOptions).Port;
                this.Init(new MICore.SerialTransport(port), _launchOptions);
            }
            else
            {
                throw new ArgumentOutOfRangeException("LaunchInfo.options");
            }

            MIDebugCommandDispatcher.AddProcess(this);

            // When the debuggee exits, we need to exit the debugger
            ProcessExitEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                ResultEventArgs results = args as MICore.Debugger.ResultEventArgs;

                if (results.Results.Contains("exit-code"))
                {
                    processExitCode = results.Results.FindUint("exit-code");
                }

                // quit MI Debugger
                _worker.PostOperation(CmdExitAsync);
                if (_waitDialog != null)
                {
                    _waitDialog.EndWaitDialog();
                }
            };

            // When the debugger exits, we tell AD7 we are done
            DebuggerExitEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                // this is the last AD7 Event we can ever send
                // Also the transport is closed when this returns
                _callback.OnProcessExit(processExitCode);

                Dispose();
            };

            DebuggerAbortedEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                // The MI debugger process unexpectedly exited.
                _worker.PostOperation(() =>
                {
                    // If the MI Debugger exits before we get a resume call, we have no way of sending program destroy. So just let start debugging fail.
                    if (!_connected)
                    {
                        return;
                    }

                    _callback.OnError(MICoreResources.Error_MIDebuggerExited);
                    _callback.OnProcessExit(uint.MaxValue);

                    Dispose();
                });
            };

            ModuleLoadEvent += async delegate(object o, EventArgs args)
            {
                // NOTE: This is an async void method, so make sure exceptions are caught and somehow reported

                if (_libraryLoaded.Count != 0)
                {
                    string moduleNames = string.Join(", ", _libraryLoaded);

                    try
                    {
                        _libraryLoaded.Clear();
                        SourceLineCache.OnLibraryLoad();

                        await _breakpointManager.BindAsync();
                        await CheckModules();

                        _bLastModuleLoadFailed = false;
                    }
                    catch (Exception e)
                    {
                        if (this.ProcessState == MICore.ProcessState.Exited)
                        {
                            return; // ignore exceptions after the process has exited
                        }

                        string exceptionDescription = EngineUtils.GetExceptionDescription(e);
                        string message = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_ExceptionProcessingModules, moduleNames, exceptionDescription);

                        // to avoid spamming the user, if the last module failed, we send the next failure to the output windiw instead of a message box
                        if (!_bLastModuleLoadFailed)
                        {
                            _callback.OnError(message);
                            _bLastModuleLoadFailed = true;
                        }
                        else
                        {
                            _callback.OnOutputMessage(message, enum_MESSAGETYPE.MT_OUTPUTSTRING);
                        }
                    }
                }
                if (_waitDialog != null)
                {
                    _waitDialog.EndWaitDialog();
                }
                if (MICommandFactory.SupportsStopOnDynamicLibLoad())
                {
                    CmdContinueAsync();
                }
            };

            // When we break we need to gather information
            BreakModeEvent += async delegate(object o, EventArgs args)
            {
                // NOTE: This is an async void method, so make sure exceptions are caught and somehow reported

                ResultEventArgs results = args as MICore.Debugger.ResultEventArgs;
                if (_waitDialog != null)
                {
                    _waitDialog.EndWaitDialog();
                }

                if (!this._connected)
                {
                    _initialBreakArgs = results;
                    return;
                }

                try
                {
                    await HandleBreakModeEvent(results);
                }
                catch (Exception e)
                {
                    if (this.ProcessState == MICore.ProcessState.Exited)
                    {
                        return; // ignore exceptions after the process has exited
                    }

                    string exceptionDescription = EngineUtils.GetExceptionDescription(e);
                    string message = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_FailedToEnterBreakState, exceptionDescription);
                    _callback.OnError(message);

                    Terminate();
                }
            };

            RunModeEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                if (!_bStarted)
                {
                    _bStarted = true;

                    // Send any strings we got before the process came up
                    if (_pendingMessages.Length != 0)
                    {
                        try
                        {
                            _callback.OnOutputString(_pendingMessages.ToString());
                        }
                        catch
                        {
                            // If something goes wrong sending the output, lets not crash VS
                        }
                    }
                    _pendingMessages = null;
                }
            };

            ErrorEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                ResultEventArgs result = (ResultEventArgs)args;
                _callback.OnError(result.Results.FindString("msg"));
            };

            ThreadCreatedEvent += delegate(object o, EventArgs args)
            {
                ResultEventArgs result = (ResultEventArgs)args;
                ThreadCache.ThreadEvent(result.Results.FindInt("id"), /*deleted */ false);
            };

            ThreadExitedEvent += delegate(object o, EventArgs args)
            {
                ResultEventArgs result = (ResultEventArgs)args;
                ThreadCache.ThreadEvent(result.Results.FindInt("id"), /*deleted*/ true);
            };

            BreakChangeEvent += _breakpointManager.BreakpointModified;
        }
Exemplo n.º 3
0
        internal async Task Eval(enum_EVALFLAGS dwFlags = 0, DAPEvalFlags dwDAPFlags = 0)
        {
            this.VerifyNotDisposed();

            await _engine.UpdateRadixAsync(_engine.CurrentRadix());    // ensure the radix value is up-to-date

            try
            {
                string consoleCommand;
                if (IsConsoleExecCmd(_strippedName, out consoleCommand))
                {
                    // special case for executing raw mi commands.
                    string consoleResults = null;

                    consoleResults = await MIDebugCommandDispatcher.ExecuteCommand(consoleCommand, _debuggedProcess, ignoreFailures : true);

                    Value         = String.Empty;
                    this.TypeName = null;

                    if (!String.IsNullOrEmpty(consoleResults))
                    {
                        _debuggedProcess.WriteOutput(consoleResults);
                    }
                }
                else
                {
                    bool canRunClipboardContextCommands = this._debuggedProcess.MICommandFactory.Mode == MIMode.Gdb && dwDAPFlags.HasFlag(DAPEvalFlags.CLIPBOARD_CONTEXT);
                    int  numElements = 200;

                    if (canRunClipboardContextCommands)
                    {
                        string showPrintElementsResult = await MIDebugCommandDispatcher.ExecuteCommand("show print elements", _debuggedProcess, ignoreFailures : true);

                        // Possible values for 'numElementsStr'
                        // "Limit on string chars or array elements to print is <number>."
                        // "Limit on string chars or array elements to print is unlimited."
                        string numElementsStr = Regex.Match(showPrintElementsResult, @"\d+").Value;
                        if (!string.IsNullOrEmpty(numElementsStr) && int.TryParse(numElementsStr, out numElements) && numElements != 0)
                        {
                            await MIDebugCommandDispatcher.ExecuteCommand("set print elements 0", _debuggedProcess, ignoreFailures : true);
                        }
                    }

                    int     threadId   = Client.GetDebuggedThread().Id;
                    uint    frameLevel = _ctx.Level;
                    Results results    = await _engine.DebuggedProcess.MICommandFactory.VarCreate(_strippedName, threadId, frameLevel, dwFlags, ResultClass.None);

                    if (results.ResultClass == ResultClass.done)
                    {
                        _internalName = results.FindString("name");
                        TypeName      = results.TryFindString("type");
                        if (results.Contains("dynamic"))
                        {
                            IsPreformatted = true;
                        }
                        if (results.Contains("dynamic") && results.Contains("has_more"))
                        {
                            CountChildren = results.FindUint("has_more");
                        }
                        else
                        {
                            CountChildren = results.FindUint("numchild");
                        }
                        if (results.Contains("displayhint"))
                        {
                            DisplayHint = results.FindString("displayhint");
                        }
                        if (results.Contains("attributes"))
                        {
                            if (results.FindString("attributes") == "noneditable")
                            {
                                _isReadonly = true;
                            }
                            _attribsFetched = true;
                        }
                        Value = results.TryFindString("value");
                        if ((Value == String.Empty || _format != null) && !string.IsNullOrEmpty(_internalName))
                        {
                            if (_format != null)
                            {
                                await Format();
                            }
                            else
                            {
                                results = await _engine.DebuggedProcess.MICommandFactory.VarEvaluateExpression(_internalName, ResultClass.None);

                                if (results.ResultClass == ResultClass.done)
                                {
                                    Value = results.FindString("value");
                                }
                                else if (results.ResultClass == ResultClass.error)
                                {
                                    SetAsError(results.FindString("msg"));
                                }
                                else
                                {
                                    Debug.Fail("Unexpected format of msg from -var-evaluate-expression");
                                }
                            }
                        }
                    }
                    else if (results.ResultClass == ResultClass.error)
                    {
                        SetAsError(results.FindString("msg"));
                    }
                    else
                    {
                        Debug.Fail("Unexpected format of msg from -var-create");
                    }

                    if (canRunClipboardContextCommands && numElements != 0)
                    {
                        await MIDebugCommandDispatcher.ExecuteCommand(string.Format(CultureInfo.InvariantCulture, "set print elements {0}", numElements), _debuggedProcess, ignoreFailures : true);
                    }
                }
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }

                UnexpectedMIResultException miException = e as UnexpectedMIResultException;
                string message;
                if (miException != null && miException.MIError != null)
                {
                    message = miException.MIError;
                }
                else
                {
                    message = e.Message;
                }

                SetAsError(string.Format(ResourceStrings.Failed_ExecCommandError, message));
            }
        }
Exemplo n.º 4
0
        internal async Task Eval(enum_EVALFLAGS dwFlags = 0)
        {
            this.VerifyNotDisposed();

            await _engine.UpdateRadixAsync(_engine.CurrentRadix());    // ensure the radix value is up-to-date

            try
            {
                string consoleCommand;
                if (IsConsoleExecCmd(_strippedName, out consoleCommand))
                {
                    // special case for executing raw mi commands.
                    string consoleResults = null;

                    consoleResults = await MIDebugCommandDispatcher.ExecuteCommand(consoleCommand, _debuggedProcess, ignoreFailures : true);

                    Value         = String.Empty;
                    this.TypeName = null;

                    if (!String.IsNullOrEmpty(consoleResults))
                    {
                        _debuggedProcess.WriteOutput(consoleResults);
                    }
                }
                else
                {
                    int     threadId   = Client.GetDebuggedThread().Id;
                    uint    frameLevel = _ctx.Level;
                    Results results    = await _engine.DebuggedProcess.MICommandFactory.VarCreate(_strippedName, threadId, frameLevel, dwFlags, ResultClass.None);

                    if (results.ResultClass == ResultClass.done)
                    {
                        _internalName = results.FindString("name");
                        TypeName      = results.TryFindString("type");
                        if (results.Contains("dynamic"))
                        {
                            IsPreformatted = true;
                        }
                        if (results.Contains("dynamic") && results.Contains("has_more"))
                        {
                            CountChildren = results.FindUint("has_more");
                        }
                        else
                        {
                            CountChildren = results.FindUint("numchild");
                        }
                        if (results.Contains("displayhint"))
                        {
                            DisplayHint = results.FindString("displayhint");
                        }
                        if (results.Contains("attributes"))
                        {
                            if (results.FindString("attributes") == "noneditable")
                            {
                                _isReadonly = true;
                            }
                            _attribsFetched = true;
                        }
                        Value = results.TryFindString("value");
                        if ((Value == String.Empty || _format != null) && !string.IsNullOrEmpty(_internalName))
                        {
                            if (_format != null)
                            {
                                await Format();
                            }
                            else
                            {
                                results = await _engine.DebuggedProcess.MICommandFactory.VarEvaluateExpression(_internalName, ResultClass.None);

                                if (results.ResultClass == ResultClass.done)
                                {
                                    Value = results.FindString("value");
                                }
                                else if (results.ResultClass == ResultClass.error)
                                {
                                    SetAsError(results.FindString("msg"));
                                }
                                else
                                {
                                    Debug.Fail("Weird msg from -var-evaluate-expression");
                                }
                            }
                        }
                    }
                    else if (results.ResultClass == ResultClass.error)
                    {
                        SetAsError(results.FindString("msg"));
                    }
                    else
                    {
                        Debug.Fail("Weird msg from -var-create");
                    }
                }
            }
            catch (Exception e)
            {
                if (e.InnerException != null)
                {
                    e = e.InnerException;
                }

                UnexpectedMIResultException miException = e as UnexpectedMIResultException;
                string message;
                if (miException != null && miException.MIError != null)
                {
                    message = miException.MIError;
                }
                else
                {
                    message = e.Message;
                }

                SetAsError(string.Format(ResourceStrings.Failed_ExecCommandError, message));
            }
        }