예제 #1
0
        /// <summary>
        /// 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. (http://msdn.microsoft.com/en-ca/library/bb161750.aspx)
        /// </summary>
        /// <param name="uContextCompare"> A value from the CONTEXT_COMPARE enumeration that determines the type of comparison. </param>
        /// <param name="compareToItems"> An array of references to the IDebugMemoryContext2 objects to compare against. </param>
        /// <param name="compareToLength"> The number of contexts in the compareToItems array. </param>
        /// <param name="foundIndex"> Returns the index of the first memory context that satisfies the comparison. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        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 VSNDK 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);
                        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 (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #2
0
        /// <summary>
        /// Gets the properties that describe this thread.
        /// (http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.debugger.interop.idebugthread100.getthreadproperties100.aspx)
        /// </summary>
        /// <param name="dwFields"> A combination of flags from the THREADPROPERTIES100 enumeration that determines which fields of
        /// ptp are to be filled in. </param>
        /// <param name="ptp"> A THREADPROPERTIES100 structure that that is filled in with the properties of the thread. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        int IDebugThread100.GetThreadProperties100(uint dwFields, THREADPROPERTIES100[] ptp)
        {
            try
            {
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_ID) != 0)
                {
                    try
                    {
                        ptp[0].dwThreadId = Convert.ToUInt32(this._id);
                    }
                    catch
                    {
                        ptp[0].dwThreadId = 0;
                    }
                    ptp[0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_ID;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_SUSPENDCOUNT) != 0)
                {
                    // VSNDK debug engine doesn't support suspending threads
                    ptp[0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_SUSPENDCOUNT;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_STATE) != 0)
                {
                    if (this._state == "running")
                    {
                        ptp[0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    }
                    else
                    {
                        ptp[0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_STOPPED;
                    }
                    ptp[0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_STATE;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_PRIORITY) != 0)
                {
                    ptp[0].bstrPriority = "Normal";
                    ptp[0].dwFields    |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_PRIORITY;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_NAME) != 0)
                {
                    ptp[0].bstrName  = _threadDisplayName;
                    ptp[0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_NAME;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_DISPLAY_NAME) != 0)
                {
                    // Thread display name is being requested
                    ptp[0].bstrDisplayName = _threadDisplayName;
                    ptp[0].dwFields       |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_DISPLAY_NAME;

                    // Give this display name a higher priority than the default (0)
                    // so that it will actually be displayed
                    ptp[0].DisplayNamePriority = 10;
                    ptp[0].dwFields           |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_DISPLAY_NAME_PRIORITY;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_LOCATION) != 0)
                {
                    ptp[0].bstrLocation = "";
                    if (__stackFrames != null)
                    {
                        foreach (AD7StackFrame frame in __stackFrames)
                        {
                            if ((frame.m_functionName != "") && (frame.m_functionName != "??"))
                            {
                                ptp[0].bstrLocation = frame.m_functionName;
                                break;
                            }
                        }
                    }
                    else
                    {
                        ptp[0].bstrLocation = getFunctionName();
                    }

                    if (ptp[0].bstrLocation == "")
                    {
                        ptp[0].bstrLocation = "[External Code]";
                    }

                    ptp[0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_LOCATION;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_CATEGORY) != 0)
                {
                    if (this._id == "1")
                    {
                        ptp[0].dwThreadCategory = (uint)enum_THREADCATEGORY.THREADCATEGORY_Main;
                    }
                    else
                    {
                        ptp[0].dwThreadCategory = (uint)enum_THREADCATEGORY.THREADCATEGORY_Worker;
                    }
                    ptp[0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_CATEGORY;
                }
                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_AFFINITY) != 0)
                {
                    // Thread cpu affinity is being requested
                    ptp[0].AffinityMask = 0;
                    ptp[0].dwFields    |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_AFFINITY;
                }

                if ((dwFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_PRIORITY_ID) != 0)
                {
                    // Thread display name is being requested
                    ptp[0].priorityId = 0;
                    ptp[0].dwFields  |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_PRIORITY_ID;
                }
                return(Constants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #3
0
        /// <summary>
        /// Retrieves a list of the stack frames for this thread. (http://msdn.microsoft.com/en-ca/library/bb145138.aspx)
        /// </summary>
        /// <param name="dwFieldSpec"> A combination of flags from the FRAMEINFO_FLAGS enumeration that specifies which fields of the
        /// FRAMEINFO structures are to be filled out. </param>
        /// <param name="nRadix"> Radix used in formatting numerical information in the enumerator. </param>
        /// <param name="ppEnum"> Returns an IEnumDebugFrameInfo2 object that contains a list of FRAMEINFO structures describing the
        /// stack frame. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        int IDebugThread2.EnumFrameInfo(enum_FRAMEINFO_FLAGS dwFieldSpec, uint nRadix, out IEnumDebugFrameInfo2 ppEnum)
        {
            if (this._id == "")
            {
                ppEnum = null;
                return(Constants.S_FALSE);
            }

            if (this._engine.evaluatedTheseFlags(this._id, dwFieldSpec))
            {
                ppEnum = new AD7FrameInfoEnum(previousFrameInfoArray);
                return(Constants.S_OK);
            }

            // Ask for general stack information.
            if ((this._id != "") && (this._id != this._engine.currentThread()._id))
            {
                _engine.eDispatcher.selectThread(this._id);
            }

            string stackResponse = _engine.eDispatcher.getStackFrames().Replace("#;;;;", "");

            if (stackResponse == "")
            {
                ppEnum = null;
                return(Constants.S_FALSE);
            }
            string[] frameStrings = stackResponse.Split('#');

            // Query the stack depth without inquiring GDB.
            int numStackFrames = frameStrings.Length;

            if (numStackFrames > 30) // limiting the amount of stackFrames to avoid VS crashing.
            {
                numStackFrames = 30;
            }

            ppEnum = null;
            try
            {
                bool        created        = false;
                FRAMEINFO[] frameInfoArray = new FRAMEINFO[numStackFrames];
                for (int i = 0; i < numStackFrames; i++)
                {
                    string[] frameInfo = frameStrings[i].Split(';');
                    if (frameInfo.Length >= 3)
                    {
                        if (frameInfo[3].Contains("~"))
                        {
                            // Need to lengthen the path used by Visual Studio.
                            StringBuilder longPathName = new StringBuilder(1024);
                            GetLongPathName(frameInfo[3], longPathName, longPathName.Capacity);
                            frameInfo[3] = longPathName.ToString();
                        }
                        AD7StackFrame frame = AD7StackFrame.create(_engine, this, frameInfo, ref created);
                        if (frame.m_thread.__stackFrames == null) // that's weird, but sometimes VS is not initializing __stackFrames, so I added this loop to avoid other problems.
                        {
                            while (frame.m_thread.__stackFrames == null)
                            {
                                frame.m_thread.__stackFrames = new ArrayList()
                                {
                                    frame
                                }
                            }
                            ;
                        }
                        frame.SetFrameInfo(dwFieldSpec, out frameInfoArray[i]);
                    }
                }
                if ((previousFrameInfoArray.Length != frameInfoArray.Length) || (created == true))
                {
                    previousFrameInfoArray = frameInfoArray;
                    ppEnum = new AD7FrameInfoEnum(frameInfoArray);
                }
                else
                {
                    bool isEqual = true;
                    for (int i = 0; i < frameInfoArray.Length; i++)
                    {
                        if (frameInfoArray[i].m_bstrFuncName != previousFrameInfoArray[i].m_bstrFuncName)
                        {
                            isEqual = false;
                            break;
                        }
                        if (frameInfoArray[i].m_dwValidFields != previousFrameInfoArray[i].m_dwValidFields)
                        {
                            isEqual = false;
                            break;
                        }
                        if (frameInfoArray[i].m_bstrLanguage != previousFrameInfoArray[i].m_bstrLanguage)
                        {
                            isEqual = false;
                            break;
                        }
                    }
                    if (!isEqual)
                    {
                        previousFrameInfoArray = frameInfoArray;
                        ppEnum = new AD7FrameInfoEnum(frameInfoArray);
                    }
                    else
                    {
                        ppEnum = new AD7FrameInfoEnum(previousFrameInfoArray);
                    }
                }

                if ((this._id != "") && (this._id != this._engine.currentThread()._id))
                {
                    _engine.eDispatcher.selectThread(this._engine.currentThread()._id);
                }

                return(Constants.S_OK);
            }
            catch (ComponentException e)
            {
                if ((this._id != "") && (this._id != this._engine.currentThread()._id))
                {
                    _engine.eDispatcher.selectThread(this._engine.currentThread()._id);
                }
                return(e.HResult);
            }
            catch (Exception e)
            {
                if ((this._id != "") && (this._id != this._engine.currentThread()._id))
                {
                    _engine.eDispatcher.selectThread(this._engine.currentThread()._id);
                }
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #4
0
        /// <summary>
        /// Gets the properties that describe this thread. (http://msdn.microsoft.com/en-ca/library/bb145602.aspx)
        /// </summary>
        /// <param name="dwFields"> A combination of flags from the THREADPROPERTY_FIELDS enumeration that determines which fields of
        /// ptp are to be filled in. </param>
        /// <param name="ptp"> A THREADPROPERTIES structure that that is filled in with the properties of the thread. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        int IDebugThread2.GetThreadProperties(enum_THREADPROPERTY_FIELDS dwFields, THREADPROPERTIES[] ptp)
        {
            try
            {
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_ID) != 0)
                {
                    try
                    {
                        ptp[0].dwThreadId = Convert.ToUInt32(this._id);
                    }
                    catch
                    {
                        ptp[0].dwThreadId = 0;
                    }
                    ptp[0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT) != 0)
                {
                    // VSNDK debug engine doesn't support suspending threads
                    ptp[0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_STATE) != 0)
                {
                    if (this._state == "running")
                    {
                        ptp[0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    }
                    else
                    {
                        ptp[0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_STOPPED;
                    }
                    ptp[0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_PRIORITY) != 0)
                {
                    ptp[0].bstrPriority = "Normal";
                    ptp[0].dwFields    |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_NAME) != 0)
                {
                    ptp[0].bstrName  = _threadDisplayName;
                    ptp[0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }
                if ((dwFields & enum_THREADPROPERTY_FIELDS.TPF_LOCATION) != 0)
                {
                    ptp[0].bstrLocation = "";
                    if (__stackFrames != null)
                    {
                        foreach (AD7StackFrame frame in __stackFrames)
                        {
                            if (frame.m_functionName != "")
                            {
                                ptp[0].bstrLocation = frame.m_functionName;
                                break;
                            }
                        }
                    }
                    if (ptp[0].bstrLocation == "")
                    {
                        ptp[0].bstrLocation = "[External Code]";
                    }

                    ptp[0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_LOCATION;
                }

                return(Constants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HResult);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #5
0
        /// <summary>
        /// Gets information about this module. (http://msdn.microsoft.com/en-ca/library/bb161975.aspx)
        /// </summary>
        /// <param name="dwFields"> A combination of flags from the MODULE_INFO_FIELDS enumeration that specify which fields of pInfo
        /// are to be filled out. </param>
        /// <param name="infoArray"> A MODULE_INFO structure that is filled in with a description of the module. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        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     = "";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_NAME;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_URL))
                {
                    info.m_bstrUrl      = "";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_URL;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_LOADADDRESS))
                {
                    info.m_addrLoadAddress = 0;
                    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 = 0;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_PREFFEREDADDRESS;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_SIZE))
                {
                    info.m_dwSize       = 0;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_SIZE;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_LOADORDER))
                {
                    info.m_dwLoadOrder  = 0;
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_LOADORDER;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_URLSYMBOLLOCATION))
                {
                    info.m_bstrUrlSymbolLocation = "";
                    info.dwValidFields          |= enum_MODULE_INFO_FIELDS.MIF_URLSYMBOLLOCATION;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_FLAGS))
                {
                    info.m_dwModuleFlags  = 0;
                    info.m_dwModuleFlags |= (enum_MODULE_FLAGS.MODULE_FLAG_SYMBOLS);
                    info.dwValidFields   |= enum_MODULE_INFO_FIELDS.MIF_FLAGS;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_VERSION))
                {
                    info.m_bstrVersion  = "";
                    info.dwValidFields |= enum_MODULE_INFO_FIELDS.MIF_VERSION;
                }
                if (dwFields.HasFlag(enum_MODULE_INFO_FIELDS.MIF_DEBUGMESSAGE))
                {
                    info.m_bstrDebugMessage = "";
                    info.dwValidFields     |= enum_MODULE_INFO_FIELDS.MIF_DEBUGMESSAGE;
                }

                infoArray[0] = info;

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