// Retrieves a list of all code contexts associated with this document context.
        // The engine sample only supports one code context per document context and
        // the code contexts are always memory addresses.
        int IDebugDocumentContext2.EnumCodeContexts(out IEnumDebugCodeContexts2 ppEnumCodeCxts)
        {
            ppEnumCodeCxts = null;

            if (_codeContext == null)
            {
                return(VSConstants.E_FAIL);
            }

            try
            {
                AD7MemoryAddress[] codeContexts = new AD7MemoryAddress[1];
                codeContexts[0] = _codeContext;
                ppEnumCodeCxts  = new AD7CodeContextEnum(codeContexts);
                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#2
0
        // Parses a text-based expression for evaluation.
        // The engine sample only supports locals and parameters so the only task here is to check the names in those collections.
        int IDebugExpressionContext2.ParseText(string pszCode,
                                               enum_PARSEFLAGS dwFlags,
                                               uint nRadix,
                                               out IDebugExpression2 ppExpr,
                                               out string pbstrError,
                                               out uint pichError)
        {
            pbstrError = null;
            pichError  = 0;
            ppExpr     = null;

            try
            {
                ppExpr = new AD7Expression(Engine, new VariableInformation(pszCode, ThreadContext, Engine, Thread));
                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#3
0
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            try
            {
                pinfo[0].dwFields = 0;

                if (dwFields.HasFlag(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS))
                {
                    pinfo[0].bstrAddress = m_address.ToString();
                    pinfo[0].dwFields   |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
                }

                // Fields not supported by the sample
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0){}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0){}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0){}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0) {}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) {}

                return(VSConstants.S_OK);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#4
0
        // Gets the document context for this stack frame. The debugger will call this when the current stack frame is changed
        // and will use it to open the correct source document for this stack frame.
        int IDebugStackFrame2.GetDocumentContext(out IDebugDocumentContext2 docContext)
        {
            docContext = null;
            try
            {
                if (mHasSource)
                {
                    // Assume all lines begin and end at the beginning of the line.
                    TEXT_POSITION begTp = new TEXT_POSITION();
                    begTp.dwColumn = 0;
                    begTp.dwLine   = mLineNum - 1;
                    TEXT_POSITION endTp = new TEXT_POSITION();
                    endTp.dwColumn = 0;
                    endTp.dwLine   = mLineNum - 1;

                    docContext = new AD7DocumentContext(mDocName, begTp, endTp, null);
                    return(VSConstants.S_OK);
                }
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(VSConstants.S_FALSE);
        }
示例#5
0
 int IDebugEngine2.ContinueFromSynchronousEvent(IDebugEvent2 aEvent)
 {
     // Called by the SDM to indicate that a synchronous debug event, previously sent by the DE to the SDM,
     // was received and processed. The only event the  engine sends in this fashion is Program Destroy.
     // It responds to that event by shutting down the engine.
     //
     // This is used in some cases - I set a BP here and it does get hit sometime during breakpoints
     // being triggered for example.
     try
     {
         if (aEvent is AD7ProgramDestroyEvent)
         {
             mEngineCallback = null;
             mProgramID      = Guid.Empty;
             mThread         = null;
             mProgNode       = null;
         }
         else
         {
             System.Diagnostics.Debug.Fail("Unknown synchronious event");
         }
     }
     catch (Exception e)
     {
         return(EngineUtils.UnexpectedException(e));
     }
     return(VSConstants.S_OK);
 }
示例#6
0
        // Gets the document context for this stack frame. The debugger will call this when the current stack frame is changed
        // and will use it to open the correct source document for this stack frame.
        int IDebugStackFrame2.GetDocumentContext(out IDebugDocumentContext2 docContext)
        {
            docContext = null;
            try
            {
                if (hasSource)
                {
                    // Assume all lines begin and end at the beginning of the line.
                    // TODO: Accurate line endings
                    var           lineNumber = (uint)LineNumber;
                    TEXT_POSITION begTp      = new TEXT_POSITION();
                    begTp.dwColumn = 0;
                    begTp.dwLine   = lineNumber - 1;
                    TEXT_POSITION endTp = new TEXT_POSITION();
                    endTp.dwColumn = 0;
                    endTp.dwLine   = lineNumber - 1;

                    docContext = new MonoDocumentContext(engine.TranslateToLocalPath(documentName), begTp, endTp, null);
                    return(VSConstants.S_OK);
                }
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(VSConstants.S_FALSE);
        }
示例#7
0
        // Binds this pending breakpoint to one or more code locations.
        int IDebugPendingBreakpoint2.Bind()
        {
            try
            {
                if (CanBind())
                {
                    Task bindTask = null;

                    _engine.DebuggedProcess.WorkerThread.RunOperation(() =>
                    {
                        bindTask = _engine.DebuggedProcess.AddInternalBreakAction(this.BindAsync);
                    });

                    bindTask.Wait(250); //wait a quarter of a second

                    if (!bindTask.IsCompleted)
                    {
                        //send a low severity warning bp. This will allow the UI to respond quickly, and if the mi debugger doesn't end up binding, this warning will get
                        //replaced by the real mi debugger error text
                        _BPError = new AD7ErrorBreakpoint(this, ResourceStrings.LongBind, enum_BP_ERROR_TYPE.BPET_SEV_LOW | enum_BP_ERROR_TYPE.BPET_TYPE_WARNING);
                        _engine.Callback.OnBreakpointError(_BPError);
                        return(VSConstants.S_FALSE);
                    }
                    else
                    {
                        return(VSConstants.S_OK);
                    }
                }
                else
                {
                    // The breakpoint could not be bound. This may occur for many reasons such as an invalid location, an invalid expression, etc...
                    _engine.Callback.OnBreakpointError(_BPError);
                    return(VSConstants.S_FALSE);
                }
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (AggregateException e)
            {
                if (e.GetBaseException() is InvalidCoreDumpOperationException)
                {
                    return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED);
                }
                else
                {
                    return(EngineUtils.UnexpectedException(e));
                }
            }
            catch (InvalidCoreDumpOperationException)
            {
                return(AD7_HRESULT.E_CRASHDUMP_UNSUPPORTED);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
        // Gets properties that describe a thread.
        int IDebugThread2.GetThreadProperties(enum_THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES[] ptp)
        {
            try
            {
                THREADPROPERTIES props = new THREADPROPERTIES();

                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_ID) != 0)
                {
                    props.dwThreadId = _debuggedThread.TargetId;
                    props.dwFields  |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT) != 0)
                {
                    // sample debug engine doesn't support suspending threads
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_STATE) != 0)
                {
                    props.dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    props.dwFields     |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_PRIORITY) != 0)
                {
                    props.bstrPriority = "Normal";
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_NAME) != 0)
                {
                    props.bstrName  = _debuggedThread.Name;
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_LOCATION) != 0)
                {
                    props.bstrLocation = GetCurrentLocation(true);
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_LOCATION;
                    if (props.bstrLocation == null)
                    {
                        // Thread deletion events may be delayed, in which case the thread object may still be present in the cache
                        // but the engine is unable to retrieve new data for it. So handle failure to get info for a dead thread.
                        props.dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_DEAD;
                        props.dwFields     |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                        props.bstrLocation  = ResourceStrings.ThreadExited;
                    }
                }

                ptp[0] = props;
                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#9
0
        // Creates an enumerator for properties associated with the stack frame, such as local variables.
        // The sample engine only supports returning locals and parameters. Other possible values include
        // class fields (this pointer), registers, exceptions...
        int IDebugStackFrame2.EnumProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, uint nRadix, ref Guid guidFilter, uint dwTimeout, out uint elementsReturned, out IEnumDebugPropertyInfo2 enumObject)
        {
            int hr;

            elementsReturned = 0;
            enumObject       = null;

            try
            {
                if (guidFilter == AD7Guids.guidFilterAllLocals ||
                    guidFilter == AD7Guids.guidFilterAllLocalsPlusArgs ||
                    guidFilter == AD7Guids.guidFilterArgs ||
                    guidFilter == AD7Guids.guidFilterLocals ||
                    guidFilter == AD7Guids.guidFilterLocalsPlusArgs)
                {
                    EnsureLocalsAndParameters();
                }

                if (guidFilter == AD7Guids.guidFilterLocalsPlusArgs ||
                    guidFilter == AD7Guids.guidFilterAllLocalsPlusArgs ||
                    guidFilter == AD7Guids.guidFilterAllLocals)
                {
                    CreateLocalsPlusArgsProperties(dwFields, out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else if (guidFilter == AD7Guids.guidFilterLocals)
                {
                    CreateLocalProperties(dwFields, out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else if (guidFilter == AD7Guids.guidFilterArgs)
                {
                    CreateParameterProperties(dwFields, out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else
                {
                    hr = VSConstants.E_NOTIMPL;
                }
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(hr);
        }
示例#10
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }

            try
            {
                AD_PROCESS_ID processId = EngineUtils.GetProcessId(rgpPrograms[0]);

                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process
                if (_pollThread == null)
                {
                    // We are being asked to debug a process when we currently aren't debugging anything
                    _pollThread = new WorkerThread();

                    _engineCallback = new EngineCallback(this, ad7Callback);

                    _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError;
                }
                else
                {
                    if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id))
                    {
                        Debug.Fail("Asked to attach to a process while we are debugging");
                        return(VSConstants.E_FAIL);
                    }
                }

                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                this.ProgramCreateEventSent = true;

                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true))
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#11
0
        // Gets properties that describe a thread.
        int IDebugThread2.GetThreadProperties(enum_THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES[] propertiesArray)
        {
            try
            {
                THREADPROPERTIES props = new THREADPROPERTIES();

                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_ID) != 0)
                {
                    props.dwThreadId = (uint)debuggedThread.Id;
                    props.dwFields  |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT) != 0)
                {
                    // sample debug engine doesn't support suspending threads
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_STATE) != 0)
                {
                    props.dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    props.dwFields     |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_PRIORITY) != 0)
                {
                    props.bstrPriority = "Normal";
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_NAME) != 0)
                {
                    props.bstrName  = ThreadNameString;
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_LOCATION) != 0)
                {
                    props.bstrLocation = GetCurrentLocation(true);
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_LOCATION;
                }

                return(VSConstants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#12
0
        int IDebugEngine2.CreatePendingBreakpoint(IDebugBreakpointRequest2 pBPRequest, out IDebugPendingBreakpoint2 ppPendingBP)
        {
            // Creates a pending breakpoint in the engine. A pending breakpoint is contains all the information needed to bind a breakpoint to
            // a location in the debuggee.

            ppPendingBP = null;
            try
            {
                BPMgr.CreatePendingBreakpoint(pBPRequest, out ppPendingBP);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
示例#13
0
        // Resume a process launched by IDebugEngineLaunch2.LaunchSuspended
        int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 process)
        {
            Debug.Assert(_pollThread != null);
            Debug.Assert(_engineCallback != null);
            Debug.Assert(_debuggedProcess != null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            try
            {
                AD_PROCESS_ID processId = EngineUtils.GetProcessId(process);

                if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id))
                {
                    return(VSConstants.S_FALSE);
                }

                // Send a program node to the SDM. This will cause the SDM to turn around and call IDebugEngine2.Attach
                // which will complete the hookup with AD7
                IDebugPort2 port;
                EngineUtils.RequireOk(process.GetPort(out port));

                IDebugDefaultPort2 defaultPort = (IDebugDefaultPort2)port;

                IDebugPortNotify2 portNotify;
                EngineUtils.RequireOk(defaultPort.GetPortNotify(out portNotify));

                EngineUtils.RequireOk(portNotify.AddProgramNode(new AD7ProgramNode(_debuggedProcess.Id)));

                if (_ad7ProgramId == Guid.Empty)
                {
                    Debug.Fail("Unexpected problem -- IDebugEngine2.Attach wasn't called");
                    return(VSConstants.E_FAIL);
                }

                // NOTE: We wait for the program create event to be continued before we really resume the process

                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true))
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#14
0
        /// <summary>
        ///     Gets properties that describe a thread..
        /// </summary>
        /// <param name="dwFields">The fields.</param>
        /// <param name="propertiesArray">The properties array.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int GetThreadProperties(enum_THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES[] propertiesArray)
        {
            try
            {
                var props = new THREADPROPERTIES();

                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_ID) != 0)
                {
                    props.dwThreadId = (uint)_debuggedThread.Id;
                    props.dwFields  |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT) != 0)
                {
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_STATE) != 0)
                {
                    props.dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    props.dwFields     |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_PRIORITY) != 0)
                {
                    props.bstrPriority = "Normal";
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_NAME) != 0)
                {
                    props.bstrName  = ThreadNameString;
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_LOCATION) != 0)
                {
                    props.bstrLocation = GetCurrentLocation();
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_LOCATION;
                }

                return(S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#15
0
        int IDebugEngineLaunch2.ResumeProcess(IDebugProcess2 aProcess)
        {
            // Resume a process launched by IDebugEngineLaunch2.LaunchSuspended
            try
            {
                // Send a program node to the SDM. This will cause the SDM to turn around and call IDebugEngine2.Attach
                // which will complete the hookup with AD7
                var xProcess = aProcess as AD7Process;
                if (xProcess == null)
                {
                    return(VSConstants.E_INVALIDARG);
                }
                IDebugPort2 xPort;
                EngineUtils.RequireOk(aProcess.GetPort(out xPort));
                var xDefPort = (IDebugDefaultPort2)xPort;
                IDebugPortNotify2 xNotify;
                EngineUtils.RequireOk(xDefPort.GetPortNotify(out xNotify));

                // This triggers Attach
                EngineUtils.RequireOk(xNotify.AddProgramNode(mProgNode));

                Callback.OnModuleLoad(mModule);
                Callback.OnSymbolSearch(mModule, xProcess.mISO.Replace("iso", "pdb"), enum_MODULE_INFO_FLAGS.MIF_SYMBOLS_LOADED);
                // Important!
                //
                // This call triggers setting of breakpoints that exist before run.
                // So it must be called before we resume the process.
                // If not called VS will call it after our 3 startup events, but thats too late.
                // This line was commented out in earlier Cosmos builds and caused problems with
                // breakpoints and timing.
                Callback.OnThreadStart(mThread);

                // Not sure what this does exactly. It was commented out before
                // but so was a lot of stuff we actually needed. If its uncommented it
                // throws:
                //  "Operation is not valid due to the current state of the object."
                //AD7EntrypointEvent.Send(this);

                // Now finally release our process to go after breakpoints are set
                mProcess.ResumeFromLaunch();
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
示例#16
0
        // Gets a description of the stack frame.
        int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo)
        {
            try
            {
                SetFrameInfo(dwFieldSpec, out pFrameInfo[0]);

                return(VSConstants.S_OK);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#17
0
        /// <summary>
        ///     Gets a description of the stack frame.
        /// </summary>
        /// <param name="dwFieldSpec">The field spec.</param>
        /// <param name="nRadix">The radix.</param>
        /// <param name="pFrameInfo">The frame information.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo)
        {
            try
            {
                SetFrameInfo(dwFieldSpec, out pFrameInfo[0]);

                return(S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#18
0
        int IDebugEngineLaunch2.TerminateProcess(IDebugProcess2 aProcess)
        {
            // This function is used to terminate a process that the SampleEngine launched
            // The debugger will call IDebugEngineLaunch2::CanTerminateProcess before calling this method.
            try
            {
                mProcess.Terminate();

                mEngineCallback.OnProcessExit(0);
                mProgram = null;
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
示例#19
0
        /// <summary>
        ///     Retrieves a list of the stack frames for this thread.
        ///     For the sample engine, enumerating the stack frames requires walking the callstack in the debuggee for this thread
        ///     and coverting that to an implementation of IEnumDebugFrameInfo2.
        ///     Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for,
        ///     and or construct it on demand instead of walking the entire stack.
        /// </summary>
        /// <param name="dwFieldSpec">The field spec.</param>
        /// <param name="nRadix">The radix.</param>
        /// <param name="enumObject">The enum object.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 enumObject)
        {
            // Ask the lower-level to perform a stack walk on this thread
            enumObject = null;

            try
            {
                var         numStackFrames = _debuggedThread.Backtrace.FrameCount;
                FRAMEINFO[] frameInfoArray;

                if (numStackFrames == 0)
                {
                    // failed to walk any frames. Only return the top frame.
                    frameInfoArray = new FRAMEINFO[0];
                    // MonoStackFrame frame = new MonoStackFrame(engine, this, debuggedThread);
                    // frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[0]);
                }
                else
                {
                    frameInfoArray = new FRAMEINFO[numStackFrames];

                    for (var i = 0; i < numStackFrames; i++)
                    {
                        var i1    = i;
                        var frame = new MonoStackFrame(_engine, this, () => _debuggedThread.Backtrace.GetFrame(i1));
                        if (_lineNumberOverride != null)
                        {
                            frame.LineNumber = _lineNumberOverride.Value;
                        }
                        frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]);
                    }
                }

                enumObject = new MonoFrameInfoEnumerator(frameInfoArray);
                return(S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#20
0
        // Gets the code context for this stack frame. The code context represents the current instruction pointer in this stack frame.
        int IDebugStackFrame2.GetCodeContext(out IDebugCodeContext2 memoryAddress)
        {
            memoryAddress = null;

            try
            {
                //memoryAddress = new AD7MemoryAddress(m_engine, m_threadContext.eip);
                return(VSConstants.E_NOTIMPL);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#21
0
        // Gets the name of the stack frame.
        // The name of a stack frame is typically the name of the method being executed.
        int IDebugStackFrame2.GetName(out string name)
        {
            name = null;

            try
            {
                name = mFunctionName;
                return(VSConstants.S_OK);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#22
0
        // Gets the code context for this stack frame. The code context represents the current instruction pointer in this stack frame.
        int IDebugStackFrame2.GetCodeContext(out IDebugCodeContext2 memoryAddress)
        {
            memoryAddress = null;

            try
            {
                memoryAddress = new MonoMemoryAddress(engine, (uint)frame().Address, null);
                return(VSConstants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#23
0
        /// <summary>
        ///     Gets the code context for this stack frame. The code context represents the current instruction pointer in this
        ///     stack frame.
        /// </summary>
        /// <param name="memoryAddress">The memory address.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int GetCodeContext(out IDebugCodeContext2 memoryAddress)
        {
            memoryAddress = null;

            try
            {
                memoryAddress = new MonoMemoryAddress(_engine, (uint)_frame().Address, null);
                return(S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#24
0
        // Retrieves a list of the stack frames for this thread.
        // For the sample engine, enumerating the stack frames requires walking the callstack in the debuggee for this thread
        // and coverting that to an implementation of IEnumDebugFrameInfo2.
        // Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for,
        // and or construct it on demand instead of walking the entire stack.
        int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 enumObject)
        {
            enumObject = null;
            try
            {
                // get the thread's stack frames
                System.Collections.Generic.List <ThreadContext> stackFrames = null;
                _engine.DebuggedProcess.WorkerThread.RunOperation(async() => stackFrames = await _engine.DebuggedProcess.ThreadCache.StackFrames(_debuggedThread));
                int         numStackFrames = stackFrames != null ? stackFrames.Count : 0;
                FRAMEINFO[] frameInfoArray;

                if (numStackFrames == 0)
                {
                    // failed to walk any frames. Return an empty stack.
                    frameInfoArray = new FRAMEINFO[0];
                }
                else
                {
                    uint low  = stackFrames[0].Level;
                    uint high = stackFrames[stackFrames.Count - 1].Level;
                    FilterUnknownFrames(stackFrames);
                    numStackFrames = stackFrames.Count;
                    frameInfoArray = new FRAMEINFO[numStackFrames];

                    for (int i = 0; i < numStackFrames; i++)
                    {
                        //var p = parameters != null ? parameters.Find((ArgumentList t) => t.Item1 == stackFrames[i].Level) : null;
                        AD7StackFrame frame = new AD7StackFrame(_engine, this, stackFrames[i]);
                        frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i], null);
                    }
                }

                enumObject = new AD7FrameInfoEnum(frameInfoArray);
                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#25
0
        // Retrieves a list of the stack frames for this thread.
        // For the sample engine, enumerating the stack frames requires walking the callstack in the debuggee for this thread
        // and coverting that to an implementation of IEnumDebugFrameInfo2.
        // Real engines will most likely want to cache this information to avoid recomputing it each time it is asked for,
        // and or construct it on demand instead of walking the entire stack.
        int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS aFieldSpec, uint aRadix, out IEnumDebugFrameInfo2 oEnumObject)
        {
            // Check mStackFrame, not address because it is possible for 2 sequential breaks to be on the same address
            // but in that case we would need a new stack frame.
            //
            // EnumFrameInfo is called several times on each break becuase "different callers can call with different flags".
            // We ignore flags through and always return full, but EnumFrameInfo gets called half a dozen times which is slow
            // if we refresh each and every time. So we cache our info.
            if (mProcess.mStackFrame == null || true)
            {
                // Ask the lower-level to perform a stack walk on this thread
                //m_engine.DebuggedProcess.DoStackWalk(this.m_debuggedThread);
                oEnumObject = null;
                try {
                    //System.Collections.Generic.List<X86ThreadContext> stackFrames = this.m_debuggedThread.StackFrames;
                    //int numStackFrames = stackFrames.Count;
                    FRAMEINFO[] xFrameInfoArray;

                    //if (numStackFrames == 0) {
                    // failed to walk any frames. Only return the top frame.

                    xFrameInfoArray = new FRAMEINFO[1];
                    var xFrame = new AD7StackFrame(mEngine, this, mProcess);
                    xFrame.SetFrameInfo((enum_FRAMEINFO_FLAGS)aFieldSpec, out xFrameInfoArray[0]);

                    //} else {
                    //frameInfoArray = new FRAMEINFO[numStackFrames];
                    //for (int i = 0; i < numStackFrames; i++) {
                    //AD7StackFrame frame = new AD7StackFrame(m_engine, this, stackFrames[i]);
                    //frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]);
                    //}
                    //}

                    mProcess.mStackFrame = new AD7FrameInfoEnum(xFrameInfoArray);
                } catch (Exception e) {
                    //catch (ComponentException e) {
                    //    return e.HResult;
                    //}
                    return(EngineUtils.UnexpectedException(e));
                }
            }
            oEnumObject = mProcess.mStackFrame;
            return(VSConstants.S_OK);
        }
示例#26
0
        // Parses a text-based expression for evaluation.
        // The engine sample only supports locals and parameters so the only task here is to check the names in those collections.
        int IDebugExpressionContext2.ParseText(string pszCode, enum_PARSEFLAGS dwFlags, uint nRadix, out IDebugExpression2 ppExpr,
                                               out string pbstrError,
                                               out uint pichError)
        {
            //System.Windows.Forms.AD7Util.MessageBox("pszCode: " + pszCode);
            pbstrError = "";
            pichError  = 0;
            ppExpr     = null;

            try
            {
                if (mParams != null)
                {
                    foreach (DebugLocalInfo currVariable in mParams)
                    {
                        if (String.CompareOrdinal(currVariable.Name, pszCode) == 0)
                        {
                            ppExpr = new AD7Expression(currVariable, mProcess, this);
                            return(VSConstants.S_OK);
                        }
                    }
                }

                if (mLocals != null)
                {
                    foreach (DebugLocalInfo currVariable in mLocals)
                    {
                        if (String.CompareOrdinal(currVariable.Name, pszCode) == 0)
                        {
                            ppExpr = new AD7Expression(currVariable, mProcess, this);
                            return(VSConstants.S_OK);
                        }
                    }
                }

                pbstrError = "Invalid Expression";
                pichError  = (uint)pbstrError.Length;
                return(VSConstants.S_FALSE);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
示例#27
0
        /// <summary>
        ///     Creates an enumerator for properties associated with the stack frame, such as local variables.
        ///     The sample engine only supports returning locals and parameters. Other possible values include
        ///     class fields (this pointer), registers, exceptions...
        /// </summary>
        /// <param name="dwFields"></param>
        /// <param name="nRadix"></param>
        /// <param name="guidFilter"></param>
        /// <param name="dwTimeout"></param>
        /// <param name="elementsReturned"></param>
        /// <param name="enumObject"></param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int EnumProperties(enum_DEBUGPROP_INFO_FLAGS dwFields, uint nRadix, ref Guid guidFilter,
                                  uint dwTimeout, out uint elementsReturned, out IEnumDebugPropertyInfo2 enumObject)
        {
            int hr;

            elementsReturned = 0;
            enumObject       = null;

            try
            {
                if ((guidFilter == Guids.FilterLocalsPlusArgs) ||
                    (guidFilter == Guids.FilterAllLocalsPlusArgs) ||
                    (guidFilter == Guids.FilterAllLocals))
                {
                    CreateLocalsPlusArgsProperties(out elementsReturned, out enumObject);
                    hr = S_OK;
                }
                else if (guidFilter == Guids.FilterLocals)
                {
                    CreateLocalProperties(out elementsReturned, out enumObject);
                    hr = S_OK;
                }
                else if (guidFilter == Guids.FilterArgs)
                {
                    CreateParameterProperties(out elementsReturned, out enumObject);
                    hr = S_OK;
                }
                else
                {
                    hr = E_NOTIMPL;
                }
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(hr);
        }
示例#28
0
 public int EnumCodeContexts(out IEnumDebugCodeContexts2 ppEnumCodeCxts)
 {
     ppEnumCodeCxts = null;
     try
     {
         var codeContexts = new MonoMemoryAddress[1];
         codeContexts[0] = address;
         ppEnumCodeCxts  = new MonoCodeContextEnum(codeContexts);
         return(VSConstants.S_OK);
     }
     catch (ComponentException e)
     {
         return(e.HResult);
     }
     catch (Exception e)
     {
         return(EngineUtils.UnexpectedException(e));
     }
 }
示例#29
0
 /// <summary>
 ///     Retrieves a list of all code contexts associated with this document context.
 /// </summary>
 /// <param name="ppEnumCodeCxts">The enumerator.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public int EnumCodeContexts(out IEnumDebugCodeContexts2 ppEnumCodeCxts)
 {
     ppEnumCodeCxts = null;
     try
     {
         var codeContexts = new IDebugCodeContext2[1];
         codeContexts[0] = _address;
         ppEnumCodeCxts  = new MonoCodeContextEnumerator(codeContexts);
         return(S_OK);
     }
     catch (ComponentException e)
     {
         return(e.HResult);
     }
     catch (Exception e)
     {
         return(EngineUtils.UnexpectedException(e));
     }
 }
示例#30
0
 // Retrieves a list of all code contexts associated with this document context.
 // The engine sample only supports one code context per document context and
 // the code contexts are always memory addresses.
 int IDebugDocumentContext2.EnumCodeContexts(out IEnumDebugCodeContexts2 ppEnumCodeCxts)
 {
     ppEnumCodeCxts = null;
     try
     {
         AD7MemoryAddress[] codeContexts = new AD7MemoryAddress[1];
         codeContexts[0] = m_codeContext;
         ppEnumCodeCxts  = new AD7CodeContextEnum(codeContexts);
         return(VSConstants.S_OK);
     }
     //catch (ComponentException e)
     //{
     //  return e.HResult;
     //}
     catch (Exception e)
     {
         return(EngineUtils.UnexpectedException(e));
     }
 }