Ejemplo n.º 1
0
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            // Attach the debug engine to a program.
            //
            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process.
            // So could we simplify and move code from LaunchSuspended to here and maybe even
            // eliminate the debughost? Although I supposed DebugHost has some other uses as well.

            if (aCeltPrograms != 1)
            {
                System.Diagnostics.Debug.Fail("Cosmos Debugger only supports one debug target at a time.");
                throw new ArgumentException();
            }

            try {
                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out mProgramID));

                mProgram = rgpPrograms[0];
                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                AD7ModuleLoadEvent.Send(this, mModule, true);

                // Dummy main thread
                // We dont support threads yet, but the debugger expects threads.
                // So we create a dummy object to represente our only "thread".
                mThread = new AD7Thread(this, mProcess);
                AD7LoadCompleteEvent.Send(this, mThread);
            } catch (Exception e) {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
Ejemplo n.º 2
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);
        }
Ejemplo n.º 3
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);
 }
Ejemplo n.º 4
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));
            }
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        // Gets a description of the stack frame.
        int IDebugStackFrame2.GetInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, FRAMEINFO[] pFrameInfo)
        {
            try {
                SetFrameInfo((enum_FRAMEINFO_FLAGS)dwFieldSpec, out pFrameInfo[0]);

                return(VSConstants.S_OK);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e) {
                return(EngineUtils.UnexpectedException(e));
            }
        }
Ejemplo n.º 8
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));
            }
        }
Ejemplo n.º 9
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));
            }
        }
Ejemplo n.º 10
0
        // Gets properties that describe a thread.
        int IDebugThread2.GetThreadProperties(enum_THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES[] propertiesArray)
        {
            try {
                THREADPROPERTIES props = new THREADPROPERTIES();

                if (dwFields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_ID))
                {
                    //props.dwThreadId = (uint)m_debuggedThread.Id;
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }
                if (dwFields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT))
                {
                    // sample debug engine doesn't support suspending threads
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }
                if (dwFields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_STATE))
                {
                    props.dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    props.dwFields     |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }
                if (dwFields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_PRIORITY))
                {
                    props.bstrPriority = "Normal";
                    props.dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }
                if (dwFields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_NAME))
                {
                    props.bstrName  = ThreadNameString;
                    props.dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }
                if (dwFields.HasFlag(enum_THREADPROPERTY_FIELDS.TPF_LOCATION))
                {
                    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));
            }
        }
Ejemplo n.º 11
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)
            {
                // 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);
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
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));
     }
 }
Ejemplo n.º 14
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.MessageBox.Show("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));
            }
        }
Ejemplo n.º 15
0
        // Gets the file statement range of the document context.
        // A statement range is the range of the lines that contributed the code to which this document context refers.
        int IDebugDocumentContext2.GetStatementRange(TEXT_POSITION[] pBegPosition, TEXT_POSITION[] pEndPosition)
        {
            try
            {
                pBegPosition[0].dwColumn = m_begPos.dwColumn;
                pBegPosition[0].dwLine   = m_begPos.dwLine;

                pEndPosition[0].dwColumn = m_endPos.dwColumn;
                pEndPosition[0].dwLine   = m_endPos.dwLine;
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }

            return(VSConstants.S_OK);
        }
Ejemplo n.º 16
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.guidFilterLocalsPlusArgs ||
                    guidFilter == AD7Guids.guidFilterAllLocalsPlusArgs)
                {
                    CreateLocalsPlusArgsProperties(out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else if (guidFilter == AD7Guids.guidFilterLocals)
                {
                    CreateLocalProperties(out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else if (guidFilter == AD7Guids.guidFilterArgs)
                {
                    CreateParameterProperties(out elementsReturned, out enumObject);
                    hr = VSConstants.S_OK;
                }
                else
                {
                    hr = VSConstants.E_NOTIMPL;
                }
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e) {
                return(EngineUtils.UnexpectedException(e));
            }

            return(hr);
        }
Ejemplo n.º 17
0
        // During startup these methods are called in this order:
        // -LaunchSuspended
        // -ResumeProcess
        //   -Attach - Triggered by Attach

        int IDebugEngineLaunch2.LaunchSuspended(string aPszServer, IDebugPort2 aPort, string aDebugInfo
                                                , string aArgs, string aDir, string aEnv, string aOptions, enum_LAUNCH_FLAGS aLaunchFlags
                                                , uint aStdInputHandle, uint aStdOutputHandle, uint hStdError, IDebugEventCallback2 aAD7Callback
                                                , out IDebugProcess2 oProcess)
        {
            // Launches a process by means of the debug engine.
            // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger
            // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program
            // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language),
            // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method
            // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state.

            oProcess = null;
            try {
                mEngineCallback = new EngineCallback(this, aAD7Callback);

                var xDebugInfo = new NameValueCollection();
                NameValueCollectionHelper.LoadFromString(xDebugInfo, aDebugInfo);

                //TODO: In the future we might support command line args for kernel etc
                //string xCmdLine = EngineUtils.BuildCommandLine(exe, args);
                //var processLaunchInfo = new ProcessLaunchInfo(exe, xCmdLine, dir, env, options, launchFlags, hStdInput, hStdOutput, hStdError);

                AD7EngineCreateEvent.Send(this);
                oProcess = mProcess = new AD7Process(xDebugInfo, mEngineCallback, this, aPort);
                // We only support one process, so just use its ID for the program ID
                mProgramID = mProcess.ID;
                //AD7ThreadCreateEvent.Send(this, xProcess.Thread);
                mModule   = new AD7Module();
                mProgNode = new AD7ProgramNode(mProcess.PhysID);
            } catch (NotSupportedException) {
                return(VSConstants.S_FALSE);
            } catch (Exception e) {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
Ejemplo n.º 18
0
        // Compares the memory context to each context in the given array in the manner indicated by compare flags,
        // returning an index of the first context that matches.
        public int Compare(enum_CONTEXT_COMPARE uContextCompare, IDebugMemoryContext2[] compareToItems, uint compareToLength, out uint foundIndex)
        {
            foundIndex = uint.MaxValue;

            try
            {
                enum_CONTEXT_COMPARE contextCompare = (enum_CONTEXT_COMPARE)uContextCompare;

                for (uint c = 0; c < compareToLength; c++)
                {
                    AD7MemoryAddress compareTo = compareToItems[c] as AD7MemoryAddress;
                    if (compareTo == null)
                    {
                        continue;
                    }

                    if (!AD7Engine.ReferenceEquals(this.m_engine, compareTo.m_engine))
                    {
                        continue;
                    }

                    bool result;

                    switch (contextCompare)
                    {
                    case enum_CONTEXT_COMPARE.CONTEXT_EQUAL:
                        result = (this.m_address == compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN:
                        result = (this.m_address < compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN:
                        result = (this.m_address > compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN_OR_EQUAL:
                        result = (this.m_address <= compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN_OR_EQUAL:
                        result = (this.m_address >= compareTo.m_address);
                        break;

                    // The sample debug engine doesn't understand scopes or functions
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_SCOPE:
                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_FUNCTION:
                        result = (this.m_address == compareTo.m_address);
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_MODULE:
                        result = (this.m_address == compareTo.m_address);
                        if (result == false)
                        {
                            //DebuggedModule module = m_engine.DebuggedProcess.ResolveAddress(m_address);

                            //if (module != null)
                            //{
                            //    result = (compareTo.m_address >= module.BaseAddress) &&
                            //        (compareTo.m_address < module.BaseAddress + module.Size);
                            //}
                        }
                        break;

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_PROCESS:
                        result = true;
                        break;

                    default:
                        // A new comparison was invented that we don't support
                        return(VSConstants.E_NOTIMPL);
                    }

                    if (result)
                    {
                        foundIndex = c;
                        return(VSConstants.S_OK);
                    }
                }

                return(VSConstants.S_FALSE);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
Ejemplo n.º 19
0
        // Binds this pending breakpoint to one or more code locations.
        int IDebugPendingBreakpoint2.Bind()
        {
            try {
                if (CanBind())
                {
                    var xDocPos = (IDebugDocumentPosition2)(Marshal.GetObjectForIUnknown(mBpRequestInfo.bpLocation.unionmember2));

                    // Get the name of the document that the breakpoint was put in
                    string xDocName;
                    EngineUtils.CheckOk(xDocPos.GetFileName(out xDocName));
                    xDocName = xDocName.ToLower(); //Bug: Some filenames were returned with the drive letter as lower case but in DocumentGUIDs it was captialised so file-not-found!

                    // Get the location in the document that the breakpoint is in.
                    var xStartPos = new TEXT_POSITION[1];
                    var xEndPos   = new TEXT_POSITION[1];
                    EngineUtils.CheckOk(xDocPos.GetRange(xStartPos, xEndPos));

                    UInt32 xAddress   = 0;
                    var    xDebugInfo = mEngine.mProcess.mDebugInfoDb;

                    // We must check for DocID. This is important because in a solution that contains many projects,
                    // VS will send us BPs from other Cosmos projects (and possibly non Cosmos ones, didnt look that deep)
                    // but we wont have them in our doc list because it contains only ones from the currently project
                    // to run.
                    Guid xDocID;
                    if (xDebugInfo.DocumentGUIDs.TryGetValue(xDocName, out xDocID))
                    {
                        // Find which Method the Doc, Line, Col are in.
                        // Must add +1 for both Line and Col. They are 0 based, while SP ones are 1 based.
                        // () around << are VERY important.. + has precedence over <<
                        Int64 xPos = (((Int64)xStartPos[0].dwLine + 1) << 32) + xStartPos[0].dwColumn + 1;

                        try
                        {
                            var potXMethods = xDebugInfo.Connection.Query(new SQLinq <Method>().Where(x => x.DocumentID == xDocID &&
                                                                                                      x.LineColStart <= xPos &&
                                                                                                      x.LineColEnd >= xPos));
                            var xMethod = potXMethods.Single();
                            var asm     = xDebugInfo.Connection.Get <AssemblyFile>(xMethod.AssemblyFileID);

                            // We have the method. Now find out what Sequence Point it belongs to.
                            var xSPs = xDebugInfo.GetSequencePoints(asm.Pathname, xMethod.MethodToken);
                            var xSP  = xSPs.Single(q => q.LineColStart <= xPos && q.LineColEnd >= xPos);

                            // We have the Sequence Point, find the MethodILOp
                            var xOp = xDebugInfo.Connection.Query(new SQLinq <MethodIlOp>().Where(q => q.MethodID == xMethod.ID && q.IlOffset == xSP.Offset)).First();

                            // Get the address of the Label
                            xAddress = xDebugInfo.AddressOfLabel(xOp.LabelName);


                            if (xAddress > 0)
                            {
                                var xBPR = new AD7BreakpointResolution(mEngine, xAddress, GetDocumentContext(xAddress));
                                var xBBP = new AD7BoundBreakpoint(mEngine, xAddress, this, xBPR);
                                mBoundBPs.Add(xBBP);
                            }

                            // Ask the symbol engine to find all addresses in all modules with symbols that match this source and line number.
                            //uint[] addresses = mEngine.DebuggedProcess.GetAddressesForSourceLocation(null, documentName, startPosition[0].dwLine + 1, startPosition[0].dwColumn);
                            lock (mBoundBPs)
                            {
                                //foreach (uint addr in addresses) {
                                //    AD7BreakpointResolution breakpointResolution = new AD7BreakpointResolution(mEngine, addr, GetDocumentContext(addr));
                                //    AD7BoundBreakpoint boundBreakpoint = new AD7BoundBreakpoint(mEngine, addr, this, breakpointResolution);
                                //    m_boundBreakpoints.Add(boundBreakpoint);
                                //    mEngine.DebuggedProcess.SetBreakpoint(addr, boundBreakpoint);
                                //}
                            }
                        }
                        catch (InvalidOperationException)
                        {
                            //No elements in potXMethods sequence!
                            return(VSConstants.S_FALSE);
                        }
                    }
                    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...
                    // The sample engine does not support this, but a real world engine will want to send an instance of IDebugBreakpointErrorEvent2 to the
                    // UI and return a valid instance of IDebugErrorBreakpoint2 from IDebugPendingBreakpoint2::EnumErrorBreakpoints. The debugger will then
                    // display information about why the breakpoint did not bind to the user.
                    return(VSConstants.S_FALSE);
                }
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e) {
                return(EngineUtils.UnexpectedException(e));
            }
        }
Ejemplo n.º 20
0
        // Gets the MODULE_INFO that describes this module.
        // This is how the debugger obtains most of the information about the module.
        int IDebugModule2.GetInfo(enum_MODULE_INFO_FIELDS dwFields, MODULE_INFO[] infoArray)
        {
            try
            {
                MODULE_INFO info = new MODULE_INFO();

                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_NAME))
                {
                    //info.m_bstrName = System.IO.Path.GetFileName(this.DebuggedModule.Name);
                    info.m_bstrName     = "DEADBEEF";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_NAME;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_URL))
                {
                    //info.m_bstrUrl = this.DebuggedModule.Name;
                    info.m_bstrUrl      = "DEADBEEF";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_URL;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_LOADADDRESS))
                {
                    //info.m_addrLoadAddress = (ulong)this.DebuggedModule.BaseAddress;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_LOADADDRESS;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_PREFFEREDADDRESS))
                {
                    // A debugger that actually supports showing the preferred base should crack the PE header and get
                    // that field. This debugger does not do that, so assume the module loaded where it was suppose to.
                    //info.m_addrPreferredLoadAddress = (ulong)this.DebuggedModule.BaseAddress;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_PREFFEREDADDRESS;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_SIZE))
                {
                    //info.m_dwSize = this.DebuggedModule.Size;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_SIZE;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_LOADORDER))
                {
                    //info.m_dwLoadOrder = this.DebuggedModule.GetLoadOrder();
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_LOADORDER;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_URLSYMBOLLOCATION))
                {
                    //if (this.DebuggedModule.SymbolsLoaded)
                    {
                        //info.m_bstrUrlSymbolLocation = this.DebuggedModule.SymbolPath;
                        info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_URLSYMBOLLOCATION;
                    }
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_FLAGS))
                {
                    info.m_dwModuleFlags = 0;
                    //if (this.DebuggedModule.SymbolsLoaded)
                    {
                        info.m_dwModuleFlags |= (enum_MODULE_FLAGS.MODULE_FLAG_SYMBOLS);
                    }
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_FLAGS;
                }


                infoArray[0] = info;

                return(VSConstants.S_OK);
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }