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

        public int OnDetachClient(CLangDebugger debugger)
        {
            LoggingUtils.PrintFunction();

            try
            {
                bool shouldContinue = false;

                ManualResetEvent detachLock = new ManualResetEvent(false);

                debugger.RunInterruptOperation(delegate(CLangDebugger _debugger)
                {
                    _debugger.GdbClient.Detach();

                    detachLock.Set();
                }, shouldContinue);

                bool detachedSignaled = detachLock.WaitOne(1000);

                if (!detachedSignaled)
                {
                    throw new InvalidOperationException("Failed to detach GDB client");
                }

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

                throw;
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public void RefreshThread(uint tid)
        {
            LoggingUtils.PrintFunction();

            try
            {
                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = string.Format("-thread-info {0}", (tid == 0) ? "" : tid.ToString());

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

                    MiResultRecord.RequireOk(resultRecord, command);

                    if (!resultRecord.HasField("threads"))
                    {
                        throw new InvalidOperationException("-thread-info result missing 'threads' field");
                    }

                    MiResultValueList threadsValueList = (MiResultValueList)resultRecord ["threads"] [0];

                    List <MiResultValue> threadsData = threadsValueList.List;

                    bool refreshedProcesses = false;

                    for (int i = threadsData.Count - 1; i >= 0; --i) // reported threads are in descending order.
                    {
                        uint id = threadsData [i] ["id"] [0].GetUnsignedInt();

                        CLangDebuggeeThread thread = GetThread(id) ?? AddThread(id);

                        if (thread.RequiresRefresh)
                        {
                            MiResultValue threadData = threadsData [i];

                            if (!refreshedProcesses)
                            {
                                AndroidDevice hostDevice = DebugProgram.DebugProcess.NativeProcess.HostDevice;

                                hostDevice.RefreshProcesses(DebugProgram.DebugProcess.NativeProcess.Pid);

                                refreshedProcesses = true;
                            }

                            thread.Refresh(ref threadData);
                        }
                    }

                    if (resultRecord.HasField("current-thread-id"))
                    {
                        CurrentThreadId = resultRecord ["current-thread-id"] [0].GetUnsignedInt();
                    }
                });
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int CreateBoundBreakpoint(string location, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
        {
            //
            // Register a new GDB breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                if (m_breakpointRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_TYPE.BPT_DATA)
                {
                    throw new NotImplementedException();
                }

                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = string.Format("-break-insert -f {0} {1}", ((m_breakpointEnabled) ? "" : "-d"), PathUtils.SantiseWindowsPath(location));

                    debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        if (resultRecord != null)
                        {
                            if (resultRecord.IsError())
                            {
                                string errorReason = "<unknown error>";

                                if (resultRecord.HasField("msg"))
                                {
                                    errorReason = resultRecord ["msg"] [0].GetString();
                                }

                                LoggingUtils.RequireOk(CreateErrorBreakpoint(errorReason, documentContext, codeContext));
                            }
                            else
                            {
                                MiResultValue breakpointData = resultRecord ["bkpt"] [0];

                                MiBreakpoint breakpoint = new MiBreakpoint(breakpointData.Values);

                                LoggingUtils.RequireOk(CreateBoundBreakpoint(breakpoint, documentContext, codeContext));
                            }
                        }
                    });
                });

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

                return(Constants.E_FAIL);
            }
        }
Пример #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugBoundBreakpoint2 Members

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

        public override int Delete()
        {
            //
            // Deletes the breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                int handle = base.Delete();

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

                LoggingUtils.RequireOk(handle);

                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = "-break-delete " + GdbBreakpoint.ID;

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

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

                return(Constants.E_FAIL);
            }
        }