////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetProgramName(out string pbstrProgramName)
        {
            //
            // Gets the name of the program.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(DebugProcess.GetName(enum_GETNAME_TYPE.GN_NAME, out pbstrProgramName));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                pbstrProgramName = string.Empty;

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugProgram3 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int ExecuteOnThread(IDebugThread2 pThread)
        {
            //
            // ExecuteOnThread is called when the Session Debug Manager (SDM) wants execution to continue and have stepping state cleared.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(AttachedEngine.NativeDebugger.NativeProgram.ExecuteOnThread(pThread));

                //LoggingUtils.RequireOk (AttachedEngine.JavaDebugger.JavaProgram.ExecuteOnThread (pThread));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int WriteDump(enum_DUMPTYPE DUMPTYPE, string pszDumpUrl)
        {
            //
            // Writes a dump to a file.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(AttachedEngine.NativeDebugger.NativeProgram.WriteDump(DUMPTYPE, pszDumpUrl));

                LoggingUtils.RequireOk(AttachedEngine.JavaDebugger.JavaProgram.WriteDump(DUMPTYPE, pszDumpUrl));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Step(IDebugThread2 pThread, enum_STEPKIND sk, enum_STEPUNIT Step)
        {
            //
            // Performs a step.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(AttachedEngine.NativeDebugger.NativeProgram.Step(pThread, sk, Step));

                //LoggingUtils.RequireOk (AttachedEngine.JavaDebugger.JavaProgram.Step (pThread, sk, Step));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Execute()
        {
            //
            // Continues running this program from a stopped state. Any previous execution state is cleared.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(AttachedEngine.NativeDebugger.NativeProgram.Execute());

                LoggingUtils.RequireOk(AttachedEngine.JavaDebugger.JavaProgram.Execute());

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetCurrentLocation(out ulong puCodeLocationId)
        {
            //
            // Returns a code location identifier that represents the current code location.
            //

            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(GetCodeLocationId(m_codeContext, out puCodeLocationId));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                puCodeLocationId = 0ul;

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int EnumCodeContexts(IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum)
        {
            //
            // Enumerates the code contexts for a given position in a source file.
            //

            LoggingUtils.PrintFunction();

            try
            {
                TEXT_POSITION [] startPos = new TEXT_POSITION [1];

                TEXT_POSITION [] endPos = new TEXT_POSITION [1];

                LoggingUtils.RequireOk(pDocPos.GetFileName(out string fileName));

                LoggingUtils.RequireOk(pDocPos.GetRange(startPos, endPos));

                DebuggeeDocumentContext documentContext = new DebuggeeDocumentContext(m_debugger.Engine, fileName, startPos [0], endPos [0]);

                CLangDebuggeeCodeContext codeContext = CLangDebuggeeCodeContext.GetCodeContextForDocumentContext(m_debugger, documentContext) ?? throw new InvalidOperationException("Failed evaluating code-context for location.");

                CLangDebuggeeCodeContext [] codeContexts = new CLangDebuggeeCodeContext [] { codeContext };

                ppEnum = new DebuggeeCodeContext.Enumerator(codeContexts);

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                ppEnum = null;

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugProgram3 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int ExecuteOnThread(IDebugThread2 pThread)
        {
            //
            // Executes the debugger program. The thread is returned to give the debugger information on which thread the user is viewing when executing the program.
            //

            LoggingUtils.PrintFunction();

            try
            {
#if false
                uint threadId;

                CLangDebuggeeThread thread = pThread as CLangDebuggeeThread;

                LoggingUtils.RequireOk(thread.GetThreadId(out threadId));

                string command = "-thread-select " + threadId;

                MiResultRecord resultRecord = m_debugger.GdbClient.SendCommand(command);

                MiResultRecord.RequireOk(resultRecord, command);

                CurrentThreadId = threadId;
#endif

                LoggingUtils.RequireOk(Execute());

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Detach()
        {
            //
            // Detaches the debugger from this program.
            //

            LoggingUtils.PrintFunction();

            Exception rethrowable = null;

            try
            {
                if (AttachedEngine == null)
                {
                    throw new InvalidOperationException();
                }

                LoggingUtils.RequireOk(AttachedEngine.Detach(this));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                rethrowable = e;

                return(Constants.E_FAIL);
            }
            finally
            {
                if (rethrowable != null)
                {
                    throw rethrowable;
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int EnumFrameInfo(enum_FRAMEINFO_FLAGS requestedFields, uint radix, out IEnumDebugFrameInfo2 enumDebugFrame)
        {
            //
            // 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 converting 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.
            //

            LoggingUtils.PrintFunction();

            try
            {
                StackTrace(uint.MaxValue);

                FRAMEINFO [] frameInfo = new FRAMEINFO [m_threadStackFrames.Count];

                for (int i = 0; i < m_threadStackFrames.Count; ++i)
                {
                    LoggingUtils.RequireOk(m_threadStackFrames [i].SetFrameInfo(requestedFields, radix, ref frameInfo [i]));
                }

                enumDebugFrame = new DebuggeeStackFrame.Enumerator(frameInfo);

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                enumDebugFrame = null;

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int SetCondition(BP_CONDITION bpCondition)
        {
            //
            // Sets or changes the condition associated with this pending breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                foreach (DebuggeeBreakpointBound boundBreakpoint in m_boundBreakpoints.ToArray())
                {
                    LoggingUtils.RequireOk(boundBreakpoint.SetCondition(bpCondition));
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #12
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggerEventListener(EnvDTE.DTE dteService, IVsDebugger debuggerService, IDebuggerConnectionService debuggerConnectionService)
        {
            m_dteService = dteService;

            m_debuggerService = debuggerService;

            m_debuggerConnectionService = debuggerConnectionService;

            LoggingUtils.RequireOk(m_debuggerService.AdviseDebuggerEvents(this, out m_debuggerServiceCookie));

            LoggingUtils.RequireOk(m_debuggerService.AdviseDebugEventCallback(this));

            //
            // Register required listener events and paired process function callbacks.
            //

            m_eventCallbacks = new Dictionary <Guid, DebuggerEventListenerDelegate> ();

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.SessionCreate)), OnSessionCreate);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.SessionDestroy)), OnSessionDestroy);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.EngineCreate)), OnEngineCreate);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.ProgramCreate)), OnProgramCreate);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.ProgramDestroy)), OnProgramDestroy);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.AttachComplete)), OnAttachComplete);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.Error)), OnError);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.DebuggerConnectionEvent)), OnDebuggerConnectionEvent);

            m_eventCallbacks.Add(ComUtils.GuidOf(typeof(DebugEngineEvent.DebuggerLogcatEvent)), OnDebuggerLogcatEvent);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugPendingBreakpoint2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int Bind()
        {
            //
            // Binds this pending breakpoint to one or more code locations.
            //

            LoggingUtils.PrintFunction();

            DebuggeeDocumentContext documentContext = null;

            DebuggeeCodeContext codeContext = null;

            string bindLocation = string.Empty;

            try
            {
                ClearErrorBreakpoints();

                if (m_breakpointDeleted)
                {
                    return(Constants.E_BP_DELETED);
                }

                LoggingUtils.RequireOk(EvaluateBreakpointLocation(out documentContext, out codeContext, out bindLocation));

                LoggingUtils.RequireOk(CreateBoundBreakpoint(bindLocation, documentContext, codeContext));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #14
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int WriteAt(IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory)
        {
            //
            // Writes the specified number of bytes of memory, starting at the specified address.
            //

            LoggingUtils.PrintFunction();

            try
            {
                CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(pStartContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

                StringBuilder stringBuilder = new StringBuilder((int)dwCount * 2);

                for (uint i = 0; i < dwCount; ++i)
                {
                    stringBuilder.Append(rgbMemory [i].ToString("x"));
                }

                string command = string.Format("-data-write-memory-bytes {0} {1} {2}", contextInfoArray [0].bstrAddressAbsolute, stringBuilder.ToString(), dwCount);

                MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command);

                MiResultRecord.RequireOk(resultRecord, command);

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #15
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override int QueryRegisters()
        {
            LoggingUtils.PrintFunction();

            try
            {
                //
                // Returns a list of registers for the current stack level.
                //

                if (!m_queriedRegisters)
                {
                    uint threadId;

                    LoggingUtils.RequireOk(m_thread.GetThreadId(out threadId));

                    string command = string.Format("-data-list-register-values --thread {0} --frame {1} r", threadId, StackLevel);

                    m_debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);

                        if (!resultRecord.HasField("register-values"))
                        {
                            throw new InvalidOperationException("Failed to retrieve list of register values");
                        }

                        MiResultValue registerValues = resultRecord ["register-values"] [0];

                        int registerValuesCount = registerValues.Values.Count;

                        Dictionary <uint, string> registerIdMapping = m_debugger.GdbClient.GetRegisterIdMapping();

                        for (int i = 0; i < registerValuesCount; ++i)
                        {
                            uint registerId = registerValues [i] ["number"] [0].GetUnsignedInt();

                            string registerValue = registerValues [i] ["value"] [0].GetString();

                            string registerName = registerIdMapping [registerId];

                            string registerNamePrettified = "$" + registerName;

                            CLangDebuggeeProperty property = new CLangDebuggeeProperty(m_debugger, this, registerNamePrettified, registerValue);

                            m_stackRegisters.TryAdd(registerNamePrettified, property);

                            LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                        }

                        m_queriedRegisters = true;
                    });
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #16
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override int QueryArgumentsAndLocals()
        {
            LoggingUtils.PrintFunction();

            try
            {
                if (!m_queriedArgumentsAndLocals)
                {
                    uint threadId;

                    LoggingUtils.RequireOk(m_thread.GetThreadId(out threadId));

                    string command = string.Format("-stack-list-variables --thread {0} --frame {1} --no-values", threadId, StackLevel);

                    m_debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);

                        if (resultRecord.HasField("variables"))
                        {
                            MiResultValue localVariables = resultRecord ["variables"] [0];

                            for (int i = 0; i < localVariables.Values.Count; ++i)
                            {
                                string variableName = localVariables [i] ["name"] [0].GetString();

                                MiVariable variable = m_debugger.VariableManager.CreateVariableFromExpression(this, variableName);

                                if (variable == null)
                                {
                                    continue;
                                }

                                CLangDebuggeeProperty property = m_debugger.VariableManager.CreatePropertyFromVariable(this, variable);

                                if (property == null)
                                {
                                    throw new InvalidOperationException();
                                }

                                if (localVariables [i].HasField("arg"))
                                {
                                    m_stackArguments.TryAdd(variableName, property);

                                    LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                                }
                                else
                                {
                                    m_stackLocals.TryAdd(variableName, property);

                                    LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                                }

                                //LoggingUtils.RequireOk (m_property.AddChildren (new DebuggeeProperty [] { property }));
                            }

                            m_queriedArgumentsAndLocals = true;
                        }
                    });
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int EvaluateBreakpointLocation(out DebuggeeDocumentContext documentContext, out DebuggeeCodeContext codeContext, out string location)
        {
            LoggingUtils.PrintFunction();

            documentContext = null;

            codeContext = null;

            location = string.Empty;

            try
            {
                switch (m_breakpointRequestInfo.bpLocation.bpLocationType)
                {
                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE:
                {
                    //
                    // Specifies the location type of the breakpoint as a line of source code.
                    //

                    string fileName;

                    IDebugDocumentPosition2 documentPostion = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember2);

                    LoggingUtils.RequireOk(documentPostion.GetFileName(out fileName));

                    bool fileInCurrentProject = true; // TODO

                    if (File.Exists(fileName) && fileInCurrentProject)
                    {
                        TEXT_POSITION [] startPos = new TEXT_POSITION [1];

                        TEXT_POSITION [] endPos = new TEXT_POSITION [1];

                        LoggingUtils.RequireOk(documentPostion.GetRange(startPos, endPos));

                        documentContext = new DebuggeeDocumentContext(m_breakpointManager.Engine, fileName, startPos [0], endPos [0]);

                        location = string.Format("\"{0}:{1}\"", fileName, startPos [0].dwLine + 1);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET:
                {
                    //
                    // Specifies the location type of the breakpoint as a code function offset.
                    //

                    string function = string.Empty;

                    IDebugFunctionPosition2 functionPosition = (IDebugFunctionPosition2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember2);

                    TEXT_POSITION [] textPos = new TEXT_POSITION [1];

                    LoggingUtils.RequireOk(functionPosition.GetFunctionName(out function));

                    LoggingUtils.RequireOk(functionPosition.GetOffset(textPos));

                    if (!string.IsNullOrEmpty(function))
                    {
                        location = function;
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT:
                {
                    //
                    // Specifies the location type of the breakpoint as a code context.
                    //

                    codeContext = ((IDebugCodeContext2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember1)) as DebuggeeCodeContext;

                    if (codeContext != null)
                    {
                        location = codeContext.Address.ToString();
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_STRING:
                {
                    //
                    // Specifies the location type of the breakpoint as a code string.
                    //

                    throw new NotImplementedException();
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_ADDRESS:
                {
                    //
                    // Specifies the location type of the breakpoint as a code address.
                    //

                    string address = Marshal.PtrToStringBSTR(m_breakpointRequestInfo.bpLocation.unionmember4);

                    if (!string.IsNullOrEmpty(address))
                    {
                        location = address;
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_DATA_STRING:
                {
                    //
                    // Specifies the location type of the breakpoint as a data string.
                    //

                    string dataExpression = Marshal.PtrToStringBSTR(m_breakpointRequestInfo.bpLocation.unionmember3);

                    if (!string.IsNullOrEmpty(dataExpression))
                    {
                        location = dataExpression;
                    }

                    break;
                }

                default:
                {
                    break;
                }
                }

                return(Constants.S_OK);
            }
            catch (NotImplementedException e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_NOTIMPL);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #18
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int CreatePendingBreakpoint(IDebugBreakpointRequest2 breakpointRequest, out IDebugPendingBreakpoint2 pendingBreakpoint)
        {
            //
            // Construct and register new pending breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                DebuggeeBreakpointPending breakpoint = null;

                BP_REQUEST_INFO [] requestInfo = new BP_REQUEST_INFO [1];

                LoggingUtils.RequireOk(breakpointRequest.GetRequestInfo(enum_BPREQI_FIELDS.BPREQI_BPLOCATION, requestInfo));

                long locationType = requestInfo [0].bpLocation.bpLocationType & (long)enum_BP_LOCATION_TYPE.BPLT_LOCATION_TYPE_MASK;

                if ((locationType & (long)enum_BP_LOCATION_TYPE.BPLT_FILE_LINE) != 0)
                {
                    //
                    // Query the associated document extension, and create a respective pending breakpoint type.
                    //

                    IDebugDocumentPosition2 documentPostion = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(requestInfo[0].bpLocation.unionmember2);

                    LoggingUtils.RequireOk(documentPostion.GetFileName(out string fileName));

                    string fileExtension = Path.GetExtension(fileName).ToLower();

                    switch (fileExtension)
                    {
                    case ".c":
                    case ".cpp":
                    case ".h":
                    case ".hpp":
                    case ".asm":
                    case ".inl":
                    {
                        breakpoint = new CLangDebuggeeBreakpointPending(Engine.NativeDebugger, this, breakpointRequest);

                        break;
                    }

                    case ".java":
                    {
                        throw new NotImplementedException();
                    }

                    default:
                    {
                        breakpoint = new DebuggeeBreakpointPending(this, breakpointRequest);

                        break;
                    }
                    }
                }
                else if ((locationType & (long)enum_BP_LOCATION_TYPE.BPLT_FUNC_OFFSET) != 0)
                {
                    throw new NotImplementedException();
                }
                else if ((locationType & (long)enum_BP_LOCATION_TYPE.BPLT_CONTEXT) != 0)
                {
                    throw new NotImplementedException();
                }
                else if ((locationType & (long)enum_BP_LOCATION_TYPE.BPLT_STRING) != 0)
                {
                    throw new NotImplementedException();
                }
                else if ((locationType & (long)enum_BP_LOCATION_TYPE.BPLT_ADDRESS) != 0)
                {
                    throw new NotImplementedException();
                }
                else if ((locationType & (long)enum_BP_LOCATION_TYPE.BPLT_RESOLUTION) != 0)
                {
                    throw new NotImplementedException();
                }
                else
                {
                    throw new NotImplementedException();
                }

                lock (m_pendingBreakpoints)
                {
                    m_pendingBreakpoints.Add(breakpoint);
                }

                pendingBreakpoint = (IDebugPendingBreakpoint2)breakpoint;

                SetDirty(true);

                return(Constants.S_OK);
            }
            catch (NotImplementedException e)
            {
                LoggingUtils.HandleException(e);

                pendingBreakpoint = null;

                return(Constants.E_NOTIMPL);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                pendingBreakpoint = null;

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetThreadProperties100(uint requestedFields, THREADPROPERTIES100 [] propertiesArray)
        {
            //
            // Gets properties that describe a thread.
            //

            LoggingUtils.PrintFunction();

            try
            {
                //
                // 9.0 (2008) thread properties.
                //

                THREADPROPERTIES [] threadProperties9 = new THREADPROPERTIES [1];

                enum_THREADPROPERTY_FIELDS requestedFields90 = (enum_THREADPROPERTY_FIELDS)0x3f;// (requestedFields & 0x3f);

                LoggingUtils.RequireOk(GetThreadProperties(requestedFields90, threadProperties9));

                propertiesArray [0].bstrLocation = threadProperties9 [0].bstrLocation;

                propertiesArray [0].bstrName = threadProperties9 [0].bstrName;

                propertiesArray [0].bstrPriority = threadProperties9 [0].bstrPriority;

                propertiesArray [0].dwSuspendCount = threadProperties9 [0].dwSuspendCount;

                propertiesArray [0].dwThreadId = threadProperties9 [0].dwThreadId;

                propertiesArray [0].dwThreadState = threadProperties9 [0].dwThreadState;

                propertiesArray [0].dwFields |= (uint)threadProperties9 [0].dwFields;

                //
                // 10.0 (2010) thread properties.
                //

                if ((requestedFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_DISPLAY_NAME) != 0)
                {
                    propertiesArray [0].bstrDisplayName = m_threadDisplayName;

                    propertiesArray [0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_DISPLAY_NAME;

                    propertiesArray [0].DisplayNamePriority = (uint)enum_DISPLAY_NAME_PRIORITY100.DISPLAY_NAM_PRI_DEFAULT_100;

                    propertiesArray [0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_DISPLAY_NAME_PRIORITY;
                }

                if ((requestedFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_CATEGORY) != 0)
                {
                    if (m_threadId == 1)
                    {
                        propertiesArray [0].dwThreadCategory = (uint)enum_THREADCATEGORY.THREADCATEGORY_Main;
                    }
                    else
                    {
                        propertiesArray [0].dwThreadCategory = (uint)enum_THREADCATEGORY.THREADCATEGORY_Worker;
                    }

                    propertiesArray [0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_CATEGORY;
                }

                if ((requestedFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_AFFINITY) != 0)
                {
                    propertiesArray [0].AffinityMask = 0;

                    propertiesArray [0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_AFFINITY;
                }

                if ((requestedFields & (uint)enum_THREADPROPERTY_FIELDS100.TPF100_PRIORITY_ID) != 0)
                {
                    propertiesArray [0].priorityId = 0;

                    propertiesArray [0].dwFields |= (uint)enum_THREADPROPERTY_FIELDS100.TPF100_PRIORITY_ID;
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #20
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int SetCondition(BP_CONDITION bpCondition)
        {
            //
            // Sets or changes the condition associated with this bound breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                int handle = base.SetCondition(bpCondition);

                if (handle == Constants.E_BP_DELETED)
                {
                    return(handle);
                }

                LoggingUtils.RequireOk(handle);

                string condition = string.Empty;

                switch (bpCondition.styleCondition)
                {
                case enum_BP_COND_STYLE.BP_COND_WHEN_TRUE:
                {
                    condition = bpCondition.bstrCondition;

                    break;
                }

                case enum_BP_COND_STYLE.BP_COND_WHEN_CHANGED:
                {
                    throw new NotImplementedException();
                }
                }

                if (!string.IsNullOrEmpty(condition))
                {
                    m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                    {
                        string command = string.Format("-break-condition {0} \"{1}\"", GdbBreakpoint.ID, condition);

                        debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                        {
                            MiResultRecord.RequireOk(resultRecord, command);
                        });
                    });
                }

                return(Constants.S_OK);
            }
            catch (NotImplementedException e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_NOTIMPL);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetThreadProperties(enum_THREADPROPERTY_FIELDS requestedFields, THREADPROPERTIES [] propertiesArray)
        {
            //
            // Gets properties that describe a thread.
            //

            LoggingUtils.PrintFunction();

            try
            {
                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_ID) != 0)
                {
                    propertiesArray [0].dwThreadId = m_threadId;

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_ID;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT) != 0)
                {
                    propertiesArray [0].dwSuspendCount = m_threadSuspendCount;

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_SUSPENDCOUNT;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_STATE) != 0)
                {
                    if (m_threadRunning)
                    {
                        propertiesArray [0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_RUNNING;
                    }
                    else
                    {
                        propertiesArray [0].dwThreadState = (uint)enum_THREADSTATE.THREADSTATE_STOPPED;
                    }

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_STATE;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_PRIORITY) != 0)
                {
                    propertiesArray [0].bstrPriority = "<unknown priority>";

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_PRIORITY;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_NAME) != 0)
                {
                    propertiesArray [0].bstrName = m_threadName;

                    propertiesArray [0].dwFields |= enum_THREADPROPERTY_FIELDS.TPF_NAME;
                }

                if ((requestedFields & enum_THREADPROPERTY_FIELDS.TPF_LOCATION) != 0)
                {
                    //
                    // The thread location (usually the topmost stack frame), typically expressed as the name of the method where execution is currently halted.
                    //

                    propertiesArray [0].bstrLocation = "[External Code]";

                    StackTrace(1); // single level depth

                    if (m_threadStackFrames.Count > 0)
                    {
                        DebuggeeStackFrame stackFrame = m_threadStackFrames [0];

                        FRAMEINFO frameInfo = new FRAMEINFO();

                        LoggingUtils.RequireOk(stackFrame.SetFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FUNCNAME, 0, ref frameInfo));

                        if (!string.IsNullOrEmpty(frameInfo.m_bstrFuncName))
                        {
                            propertiesArray [0].bstrLocation = frameInfo.m_bstrFuncName;
                        }
                    }

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

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int EnumCodePaths (string pszHint, IDebugCodeContext2 pStart, IDebugStackFrame2 pFrame, int fSource, out IEnumCodePaths2 ppEnum, out IDebugCodeContext2 ppSafety)
    {
      // 
      // Enumerates the code paths of this program.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        // 
        // Get the entire call-stack for the current thread, and enumerate.
        // 

        CLangDebuggeeStackFrame stackFrame = pFrame as CLangDebuggeeStackFrame;

        IDebugThread2 thread;

        LoggingUtils.RequireOk (stackFrame.GetThread (out thread));

        CLangDebuggeeThread stackFrameThread = thread as CLangDebuggeeThread;

        List<DebuggeeStackFrame> threadCallStack = stackFrameThread.StackTrace (uint.MaxValue);

        List <CODE_PATH> threadCodePaths = new List <CODE_PATH> ();

        for (int i = 0; i < threadCallStack.Count; ++i)
        {
          string frameName;

          IDebugCodeContext2 codeContext;

          DebuggeeStackFrame frame = threadCallStack [i] as DebuggeeStackFrame;

          LoggingUtils.RequireOk (frame.GetName (out frameName));

          LoggingUtils.RequireOk (frame.GetCodeContext (out codeContext));

          if (codeContext != null)
          {
            CODE_PATH codePath = new CODE_PATH ();

            codePath.bstrName = frameName;

            codePath.pCode = codeContext;

            threadCodePaths.Add (codePath);
          }
        }

        ppEnum = new DebuggeeProgram.EnumeratorCodePaths (threadCodePaths);

        ppSafety = null;

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        ppEnum = null;

        ppSafety = null;

        return Constants.E_FAIL;
      }
    }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public async Task <DebugLaunchSettings> StartWithDebugging(int launchOptions, LaunchConfiguration launchConfig, ICollection <LaunchProps> launchProps, IDictionary <string, string> projectProperties)
        {
            LoggingUtils.PrintFunction();

            if (launchConfig == null)
            {
                throw new ArgumentNullException(nameof(launchConfig));
            }

            if (launchProps == null)
            {
                throw new ArgumentNullException(nameof(launchProps));
            }

            if (projectProperties == null)
            {
                throw new ArgumentNullException(nameof(projectProperties));
            }

            //
            // Refresh ADB service and evaluate a list of connected devices or emulators.
            //

            AndroidAdb.Refresh();

            AndroidDevice debuggingDevice = GetPrioritisedConnectedDevice() ?? throw new InvalidOperationException("No device/emulator found or connected. Check status using \"adb devices\".");

            //
            // Enforce required device/emulator properties.
            //

            foreach (var prop in launchProps)
            {
                debuggingDevice.Shell("setprop", string.Format(CultureInfo.InvariantCulture, "{0} {1}", prop.Item1, prop.Item2));
            }

            //
            // Construct VS launch settings to debug or attach to the specified target application.
            //

            bool shouldAttach = false;

#if false
            AndroidProcess [] debuggingDeviceProcesses = debuggingDevice.GetProcesses();

            foreach (AndroidProcess process in debuggingDeviceProcesses)
            {
                if (process.Name.Equals(applicationPackageName))
                {
                    shouldAttach = true;

                    break;
                }
            }
#endif

            launchOptions |= (int)DebugLaunchOptions.Silent;

            DebugLaunchSettings debugLaunchSettings = new DebugLaunchSettings((DebugLaunchOptions)launchOptions);

            debugLaunchSettings.LaunchDebugEngineGuid = new Guid("8310DAF9-1043-4C8E-85A0-FF68896E1922");

            debugLaunchSettings.PortSupplierGuid = new Guid("3AEE417F-E5F9-4B89-BC31-20534C99B7F5");

            debugLaunchSettings.PortName = debuggingDevice.ID;

            debugLaunchSettings.Options = launchConfig.ToString();

            if (shouldAttach)
            {
                debugLaunchSettings.Executable = launchConfig ["PackageName"];

                debugLaunchSettings.LaunchOperation = DebugLaunchOperation.AlreadyRunning;
            }
            else
            {
                //
                // Determine whether the application is currently installed, and if it is;
                // check last modified date to ensure we don't re-installed unchanged binaries.
                //

                bool upToDateCheck = launchConfig ["UpToDateCheck"].Equals("true");

                bool appIsInstalled = false;

                bool appIsOutOfDate = true;

                if (upToDateCheck)
                {
                    FileInfo targetApkFileInfo = new FileInfo(launchConfig ["TargetApk"]);

                    try
                    {
                        var adbPmPathOutput = debuggingDevice.Shell("pm", "path " + launchConfig ["PackageName"]).Replace("\r", "").Split(new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

                        foreach (string line in adbPmPathOutput)
                        {
                            if (line.StartsWith("package:", StringComparison.OrdinalIgnoreCase))
                            {
                                appIsInstalled = true;

                                LoggingUtils.RequireOk(await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "'{0}' already installed on target '{1}'.", launchConfig ["PackageName"], debuggingDevice.ID), false));

                                string path = line.Substring("package:".Length);

                                //
                                // Get the target device/emulator's UTC current time.
                                //
                                //   This is done by specifying the '-u' argument to 'date'. Despite this though,
                                //   the returned string will always claim to be in GMT:
                                //
                                //   i.e: "Fri Jan  9 14:35:23 GMT 2015"
                                //

                                DateTime debuggingDeviceUtcTime;

                                try
                                {
                                    var deviceDateOutput = debuggingDevice.Shell("date", "-u").Replace("\r", "").Split(new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

                                    string debuggingDeviceUtcTimestamp = deviceDateOutput [0];

                                    var debuggingDeviceUtcTimestampComponents = debuggingDeviceUtcTimestamp.Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                                    debuggingDeviceUtcTimestampComponents [4] = "-00:00";

                                    if (!DateTime.TryParseExact(string.Join(" ", debuggingDeviceUtcTimestampComponents), "ddd MMM  d HH:mm:ss zzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out debuggingDeviceUtcTime))
                                    {
                                        break;
                                    }

                                    debuggingDeviceUtcTime = debuggingDeviceUtcTime.ToUniversalTime();
                                }
                                catch (Exception e)
                                {
                                    throw new InvalidOperationException("Failed to evaluate device local time.", e);
                                }

                                //
                                // Convert current device/emulator time to UTC, and probe the working machine's time too.
                                //

                                DateTime thisMachineUtcTime = DateTime.UtcNow;

                                TimeSpan thisMachineUtcVersusDeviceUtc = debuggingDeviceUtcTime - thisMachineUtcTime;

                                await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "Current UTC time on '{0}': {1}", debuggingDevice.ID, debuggingDeviceUtcTime.ToString()), false);

                                await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "Current UTC time on '{0}': {1}", System.Environment.MachineName, thisMachineUtcTime.ToString()), false);

                                await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "Difference in UTC time between '{0}' and '{1}': {2}", System.Environment.MachineName, debuggingDevice.ID, thisMachineUtcVersusDeviceUtc.ToString()), false);

                                //
                                // Check the last modified date; ls output currently uses this format:
                                //
                                // -rw-r--r-- system   system   11533274 2015-01-09 13:47 com.example.native_activity-2.apk
                                //

                                DateTime lastModifiedTimestampDeviceLocalTime;

                                try
                                {
                                    var extendedLsOutput = debuggingDevice.Shell("ls -l", path).Replace("\r", "").Split(new char [] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

                                    var extendedLsOutputComponents = extendedLsOutput [0].Split(new char [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                                    string date = extendedLsOutputComponents [4];

                                    string time = extendedLsOutputComponents [5];

                                    if (!DateTime.TryParseExact(date + " " + time, "yyyy-MM-dd HH:mm", CultureInfo.InvariantCulture, DateTimeStyles.AllowWhiteSpaces, out lastModifiedTimestampDeviceLocalTime))
                                    {
                                        break;
                                    }
                                }
                                catch (Exception e)
                                {
                                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Failed to evaluate device local modified time of: {0}", path), e);
                                }

                                //
                                // Calculate how long ago the APK was changed, according to the device's local time.
                                //

                                TimeSpan timeSinceLastModification = debuggingDeviceUtcTime - lastModifiedTimestampDeviceLocalTime;

                                DateTime debuggingDeviceUtcTimeAtLastModification = debuggingDeviceUtcTime - timeSinceLastModification;

                                DateTime thisMachineUtcTimeAtLastModification = thisMachineUtcTime - timeSinceLastModification;

                                await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "'{0}' was last modified on '{1}' at: {2}.", launchConfig ["PackageName"], debuggingDevice.ID, debuggingDeviceUtcTimeAtLastModification.ToString()), false);

                                await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "{0} (on {1}) was around {2} (on {3}).", debuggingDeviceUtcTimeAtLastModification.ToString(), debuggingDevice.ID, thisMachineUtcTimeAtLastModification.ToString(), System.Environment.MachineName), false);

                                await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "'{0}' was last modified on '{1}' at: {2}.", Path.GetFileName(targetApkFileInfo.FullName), System.Environment.MachineName, targetApkFileInfo.LastWriteTime.ToString()), false);

                                if ((targetApkFileInfo.LastWriteTime + thisMachineUtcVersusDeviceUtc) > thisMachineUtcTimeAtLastModification)
                                {
                                    await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "'{0}' was determined to be out-of-date. Reinstalling...", launchConfig ["PackageName"]), false);
                                }
                                else
                                {
                                    appIsOutOfDate = false;
                                }

                                break;
                            }
                        }
                    }
                    catch (Exception)
                    {
                        appIsInstalled = false;
                    }
                }
                else
                {
                    await m_debugConnectionService.LaunchDialogUpdate("Skipping up-to-date check.", false);
                }

                if (!appIsInstalled || appIsOutOfDate)
                {
                    await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "Installing '{0}' to '{1}'...", launchConfig ["PackageName"], debuggingDevice.ID), false);

                    InstallApplicationAsync(debuggingDevice, launchConfig);

                    await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "'{0}' installed successfully.", launchConfig ["PackageName"]), false);
                }
                else
                {
                    await m_debugConnectionService.LaunchDialogUpdate(string.Format(CultureInfo.InvariantCulture, "'{0}' on '{1}' is up-to-date. Skipping installation...", launchConfig ["PackageName"], debuggingDevice.ID), false);
                }

                debugLaunchSettings.Executable = launchConfig ["TargetApk"];

                debugLaunchSettings.LaunchOperation = DebugLaunchOperation.Custom;
            }

            return(debugLaunchSettings);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetInfo(enum_PROCESS_INFO_FIELDS Fields, PROCESS_INFO [] infoArray)
        {
            //
            // Gets a description of the process.
            //

            LoggingUtils.PrintFunction();

            try
            {
                infoArray [0] = new PROCESS_INFO();

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_FILE_NAME) != 0)
                {
                    LoggingUtils.RequireOk(GetName(enum_GETNAME_TYPE.GN_FILENAME, out infoArray [0].bstrFileName));

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_FILE_NAME;
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_BASE_NAME) != 0)
                {
                    LoggingUtils.RequireOk(GetName(enum_GETNAME_TYPE.GN_BASENAME, out infoArray [0].bstrBaseName));

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_BASE_NAME;
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_TITLE) != 0)
                {
                    LoggingUtils.RequireOk(GetName(enum_GETNAME_TYPE.GN_TITLE, out infoArray [0].bstrTitle));

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_TITLE;
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_PROCESS_ID) != 0)
                {
                    AD_PROCESS_ID [] processId = new AD_PROCESS_ID [1];

                    LoggingUtils.RequireOk(GetPhysicalProcessId(processId));

                    infoArray [0].ProcessId = processId [0];

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_PROCESS_ID;
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_SESSION_ID) != 0)
                {
                    // We currently don't support multiple sessions, so all processes are in session 1.

                    infoArray [0].dwSessionId = 1;

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_SESSION_ID;
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_ATTACHED_SESSION_NAME) != 0)
                {
                    // Oddly enough, SESSION_NAME is requested... even though the docs clearly state that it's deprecated.

                    infoArray [0].bstrAttachedSessionName = "[Attached session name is deprecated]";

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_ATTACHED_SESSION_NAME;
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_CREATION_TIME) != 0)
                {
                    // Not entirely clear how this should be implemented.

                    /*Microsoft.VisualStudio.OLE.Interop.FILETIME filetime;
                     *
                     * infoArray [0].CreationTime = filetime;
                     *
                     * infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_CREATION_TIME;*/
                }

                if ((Fields & enum_PROCESS_INFO_FIELDS.PIF_FLAGS) != 0)
                {
                    infoArray [0].Flags |= enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_RUNNING;

                    if (DebuggeeProgram.AttachedEngine != null)
                    {
                        infoArray [0].Flags |= enum_PROCESS_INFO_FLAGS.PIFLAG_DEBUGGER_ATTACHED;
                    }

                    //enum_PROCESS_INFO_FLAGS.PIFLAG_DEBUGGER_ATTACHED
                    //enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_STOPPED
                    //enum_PROCESS_INFO_FLAGS.PIFLAG_PROCESS_RUNNING

                    if (!NativeProcess.IsUserProcess)
                    {
                        infoArray [0].Flags |= enum_PROCESS_INFO_FLAGS.PIFLAG_SYSTEM_PROCESS;
                    }

                    infoArray [0].Fields |= enum_PROCESS_INFO_FIELDS.PIF_FLAGS;
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
Example #25
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeProperty EvaluateCustomExpression(enum_EVALFLAGS evaluateFlags, string expression, uint radix)
        {
            //
            // Evaluates a custom property lookup, and registers a new entry for this expression if one can't be found.
            //

            LoggingUtils.PrintFunction();

            DebuggeeProperty property = null;

            try
            {
                if (m_stackRegisters.TryGetValue(expression, out property))
                {
                    return(property);
                }

                if (m_stackArguments.TryGetValue(expression, out property))
                {
                    return(property);
                }

                if (m_stackLocals.TryGetValue(expression, out property))
                {
                    return(property);
                }

                if (m_customExpressions.TryGetValue(expression, out property))
                {
                    return(property);
                }


                //
                // Check if this expression has already been queried via a child property.
                //

                // TODO.

                //
                // Couldn't find a pre-registered matching property for this expression, creating a new custom one.
                //

                MiVariable customExpressionVariable = m_debugger.VariableManager.CreateVariableFromExpression(this, expression);

                if (customExpressionVariable != null)
                {
                    property = m_debugger.VariableManager.CreatePropertyFromVariable(this, customExpressionVariable);

                    if (property != null)
                    {
                        m_customExpressions.TryAdd(expression, property);

                        LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                    }
                }
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);
            }

            return(property);
        }
Example #26
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region DebugEngineCallbackInterface Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            LoggingUtils.Print("[DebugEngineCallback] Event: " + riidEvent.ToString());

            //
            // Process any registered function handler before passing the event to AD7 callback.
            //

            int handle = Constants.E_NOTIMPL;

            try
            {
                DebuggerEventDelegate eventCallback;

                if (m_debuggerCallback.TryGetValue(riidEvent, out eventCallback))
                {
                    handle = eventCallback(pEngine, pProcess, pProgram, pThread, pEvent, ref riidEvent, dwAttrib);
                }

                if (handle != Constants.E_NOTIMPL)
                {
                    LoggingUtils.RequireOk(handle);
                }
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                throw;
            }
            finally
            {
                try
                {
                    handle = m_ad7EventCallback.Event(pEngine, pProcess, pProgram, pThread, pEvent, ref riidEvent, dwAttrib);

                    if (handle != Constants.E_NOTIMPL)
                    {
                        LoggingUtils.RequireOk(handle);
                    }
                }
                catch (Exception e)
                {
                    LoggingUtils.HandleException(e);

                    throw;
                }
            }

            //
            // (Managed Code) It is strongly advised that ReleaseComObject be invoked on the various interfaces that are passed to IDebugEventCallback2::Event.
            //

#if false
            Marshal.ReleaseComObject(pEngine);

            Marshal.ReleaseComObject(pProcess);

            Marshal.ReleaseComObject(pProgram);

            Marshal.ReleaseComObject(pThread);

            Marshal.ReleaseComObject(pEvent);
#endif

            return(handle);
        }
Example #27
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int SetFrameInfo(enum_FRAMEINFO_FLAGS requestedFlags, uint radix, ref FRAMEINFO frameInfo)
        {
            LoggingUtils.PrintFunction();

            try
            {
                frameInfo.m_dwValidFields = 0;

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME) != 0)
                {
                    StringBuilder functionName = new StringBuilder();

                    functionName.Append("[" + m_locationAddress.ToString() + "] ");

                    if (((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_MODULE) != 0) && (!string.IsNullOrEmpty(m_locationModule)))
                    {
                        functionName.Append(m_locationModule + "!");
                    }

                    functionName.Append(m_locationFunction);

                    /*if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_ARGS) != 0)
                     * {
                     * functionName.Append ("(...)");
                     * }
                     *
                     * if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_FUNCNAME_LINES) != 0)
                     * {
                     * functionName.AppendFormat (" Line {0}", "?");
                     * }*/

                    frameInfo.m_bstrFuncName = functionName.ToString();

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FUNCNAME;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_RETURNTYPE) != 0)
                {
                    frameInfo.m_bstrReturnType = "<return type>";

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_RETURNTYPE;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_ARGS) != 0)
                {
                    frameInfo.m_bstrArgs = m_stackArguments.Keys.ToString();

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_ARGS;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_LANGUAGE) != 0)
                {
                    string languageName = string.Empty;

                    Guid languageGuid = Guid.Empty;

                    GetLanguageInfo(ref languageName, ref languageGuid);

                    frameInfo.m_bstrLanguage = languageName;

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_LANGUAGE;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_MODULE) != 0)
                {
                    frameInfo.m_bstrModule = m_locationModule;

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_MODULE;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_STACKRANGE) != 0)
                {
                    frameInfo.m_addrMin = 0ul;

                    frameInfo.m_addrMax = 0ul;

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STACKRANGE;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_FRAME) != 0)
                {
                    frameInfo.m_pFrame = this;

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_FRAME;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO) != 0)
                {
                    frameInfo.m_fHasDebugInfo = (m_locationIsSymbolicated) ? 1 : 0;

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUGINFO;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_STALECODE) != 0)
                {
                    frameInfo.m_fStaleCode = 0;

                    frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_STALECODE;
                }

                if ((requestedFlags & enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP) != 0)
                {
                    if (!string.IsNullOrEmpty(m_locationModule))
                    {
                        IDebugProgram2 debugProgram;

                        IEnumDebugModules2 debugProgramModules;

                        uint debugModulesCount = 0;

                        LoggingUtils.RequireOk(m_thread.GetProgram(out debugProgram));

                        LoggingUtils.RequireOk(debugProgram.EnumModules(out debugProgramModules));

                        LoggingUtils.RequireOk(debugProgramModules.GetCount(out debugModulesCount));

                        DebuggeeModule [] debugModules = new DebuggeeModule [debugModulesCount];

                        LoggingUtils.RequireOk(debugProgramModules.Next(debugModulesCount, debugModules, ref debugModulesCount));

                        for (int i = 0; i < debugModulesCount; ++i)
                        {
                            if (m_locationModule.Equals(debugModules [i].Name))
                            {
                                frameInfo.m_pModule = debugModules [i];

                                frameInfo.m_dwValidFields |= enum_FRAMEINFO_FLAGS.FIF_DEBUG_MODULEP;

                                break;
                            }
                        }
                    }
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugProperty2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int EnumChildren(enum_DEBUGPROP_INFO_FLAGS dwFields, uint dwRadix, ref Guid guidFilter, enum_DBG_ATTRIB_FLAGS dwAttribFilter, string pszNameFilter, uint dwTimeout, out IEnumDebugPropertyInfo2 ppEnum)
        {
            //
            // Enumerates the children of a property. This provides support for dereferencing pointers, displaying members of an array, or fields of a class or struct.
            //

            LoggingUtils.PrintFunction();

            try
            {
                List <DEBUG_PROPERTY_INFO> childPropertyInfo = new List <DEBUG_PROPERTY_INFO> ();

                List <DebuggeeProperty> childRegisterProperties = new List <DebuggeeProperty> ();

                foreach (DebuggeeProperty child in m_children)
                {
                    bool displayProperty = false;

                    DEBUG_PROPERTY_INFO [] infoArray = new DEBUG_PROPERTY_INFO [1];

                    LoggingUtils.RequireOk(child.GetPropertyInfo(dwFields, dwRadix, dwTimeout, null, 0, infoArray));

                    if ((guidFilter == DebuggeeProperty.Filters.guidFilterRegisters) ||
                        (guidFilter == DebuggeeProperty.Filters.guidFilterAutoRegisters))
                    {
                        if ((infoArray [0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_STORAGE_REGISTER) != 0)
                        {
                            childRegisterProperties.Add(child);
                        }
                    }
                    else if ((guidFilter == DebuggeeProperty.Filters.guidFilterArgs) ||
                             (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs) ||
                             (guidFilter == DebuggeeProperty.Filters.guidFilterLocalsPlusArgs))
                    {
                        displayProperty |= ((infoArray [0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_DATA) != 0);
                    }
                    else if ((guidFilter == DebuggeeProperty.Filters.guidFilterAllLocals) ||
                             (guidFilter == DebuggeeProperty.Filters.guidFilterAllLocalsPlusArgs) ||
                             (guidFilter == DebuggeeProperty.Filters.guidFilterLocals) ||
                             (guidFilter == DebuggeeProperty.Filters.guidFilterLocalsPlusArgs))
                    {
                        displayProperty |= ((infoArray [0].dwAttrib & enum_DBG_ATTRIB_FLAGS.DBG_ATTRIB_DATA) != 0);
                    }
                    else
                    {
                        displayProperty = true;
                    }

                    /*if ((infoArray [0].dwAttrib & dwAttribFilter) != 0)
                     * {
                     * displayProperty = false;
                     * }*/

                    if (displayProperty)
                    {
                        childPropertyInfo.Add(infoArray [0]);
                    }
                }

                if ((guidFilter == DebuggeeProperty.Filters.guidFilterRegisters) ||
                    (guidFilter == DebuggeeProperty.Filters.guidFilterAutoRegisters))
                {
                    //
                    //
                    // Registers must be specified in a collection/list as children of a 'CPU' property.
                    //
                    // Other types documented: https://msdn.microsoft.com/en-us/library/aa290860(v=vs.71).aspx
                    //

                    DebuggeeProperty registersProperty = new DebuggeeProperty(m_debugEngine, m_stackFrame, "CPU", string.Empty);

                    LoggingUtils.RequireOk(registersProperty.AddChildren(childRegisterProperties.ToArray()));

                    DEBUG_PROPERTY_INFO [] infoArray = new DEBUG_PROPERTY_INFO [1];

                    LoggingUtils.RequireOk(registersProperty.GetPropertyInfo(dwFields, dwRadix, dwTimeout, null, 0, infoArray));

                    childPropertyInfo.Add(infoArray [0]);
                }

                ppEnum = new DebuggeeProperty.Enumerator(childPropertyInfo);

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                ppEnum = null;

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugPortSupplier2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int AddPort(IDebugPortRequest2 pRequest, out IDebugPort2 ppPort)
        {
            //
            // Attempt to find a port matching the requested name, otherwise one is created.
            //

            LoggingUtils.PrintFunction();

            try
            {
                string requestPortName;

                LoggingUtils.RequireOk(CanAddPort());

                LoggingUtils.RequireOk(pRequest.GetPortName(out requestPortName));

                if (string.IsNullOrWhiteSpace(requestPortName))
                {
                    throw new InvalidOperationException("Invalid/empty port name");
                }

                ppPort = null;

                foreach (KeyValuePair <Guid, IDebugPort2> keyPair in m_registeredPorts)
                {
                    string portName;

                    IDebugPort2 registeredPort = keyPair.Value;

                    LoggingUtils.RequireOk(registeredPort.GetPortName(out portName));

                    if (portName.Equals(requestPortName))
                    {
                        ppPort = registeredPort;

                        break;
                    }
                }

                if (ppPort == null)
                {
                    //
                    // Create and track a new port for this request.
                    //

                    Guid portId;

                    LoggingUtils.RequireOk(CreatePort(pRequest, out ppPort));

                    LoggingUtils.RequireOk(ppPort.GetPortId(out portId));

                    m_registeredPorts.Add(portId, ppPort);
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                ppPort = null;

                return(Constants.E_FAIL);
            }
        }
Example #30
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int SetPassCount(BP_PASSCOUNT bpPassCount)
        {
            //
            // Sets or change the pass count associated with this bound breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                int handle = base.SetPassCount(bpPassCount);

                if (handle == Constants.E_BP_DELETED)
                {
                    return(handle);
                }

                LoggingUtils.RequireOk(handle);

                uint passCount = 0;

                switch (bpPassCount.stylePassCount)
                {
                case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_EQUAL:
                {
                    goto case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_EQUAL_OR_GREATER;
                }

                case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_EQUAL_OR_GREATER:
                {
                    passCount = bpPassCount.dwPassCount - 1;

                    break;
                }

                case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_MOD:
                {
                    throw new NotImplementedException();
                }
                }

                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = string.Format("-break-after {0} {1}", GdbBreakpoint.ID, passCount);

                    debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);
                    });
                });

                return(Constants.S_OK);
            }
            catch (NotImplementedException e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_NOTIMPL);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }