Exemple #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int OnError(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            LoggingUtils.PrintFunction();

            try
            {
                DebugEngineEvent.Error errorEvent = pEvent as DebugEngineEvent.Error;

                enum_MESSAGETYPE [] messageType = new enum_MESSAGETYPE [1];

                string errorFormat, errorHelpFileName;

                int errorReason;

                uint errorType, errorHelpId;

                LoggingUtils.RequireOk(errorEvent.GetErrorMessage(messageType, out errorFormat, out errorReason, out errorType, out errorHelpFileName, out errorHelpId));

                LoggingUtils.RequireOk(m_debuggerConnectionService.LaunchDialogUpdate(errorFormat, true));

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

                return(VSConstants.E_FAIL);
            }
        }
Exemple #2
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #endregion

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

        #region IDebugEventCallback2 Members

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

        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            try
            {
                DebuggerEventListenerDelegate callback;

                LoggingUtils.Print("[DebuggerEventListener] Event: " + riidEvent.ToString());

                int handle = VsDebugCommon.Constants.E_NOTIMPL;

                if (!m_eventCallbacks.TryGetValue(riidEvent, out callback))
                {
                    return(handle);
                }

                handle = callback(pEngine, pProcess, pProgram, pThread, pEvent, ref riidEvent, dwAttrib);

                if (handle != VsDebugCommon.Constants.E_NOTIMPL)
                {
                    LoggingUtils.RequireOk(handle);
                }

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

                return(VSConstants.E_FAIL);
            }
        }
 public SynchronousJob(JoinableTaskContext taskContext,
                       IDebugEngine2 debugEngine, IDebugEvent2 evnt)
 {
     this.taskContext = taskContext;
     this.debugEngine = debugEngine;
     this.evnt        = evnt;
 }
Exemple #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            //
            // Custom event handler.
            //

            try
            {
                LoggingUtils.Print("[CLangDebuggerCallback] Event: " + riidEvent.ToString());

                CLangDebuggerEventDelegate eventCallback;

                if (!m_debuggerCallback.TryGetValue(riidEvent, out eventCallback))
                {
                    return(Constants.E_NOTIMPL);
                }

                return(eventCallback(m_debugEngine.NativeDebugger));
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                throw;
            }
        }
Exemple #5
0
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program,
                         IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
        {
            if (!(debugEvent is IDebugProcessCreateEvent2) &&
                !(debugEvent is IDebugProcessDestroyEvent2))
            {
                return(VSConstants.S_OK);
            }

            var target = GetTargetFromProcess(process);

            if (target == null)
            {
                _package.Reporter.ReportWarning("Can't find target from process {0} ({1}). Event: {2}.",
                                                process.GetName(), process.GetProcessId(), TypeHelper.GetDebugEventTypeName(debugEvent));
                return(VSConstants.S_OK);
            }

            if (debugEvent is IDebugProcessCreateEvent2)
            {
                target.IsAttached = true;
                _package.History.Items.AddFirst(target);
                _package.Ui.Update();
            }
            else
            {
                target.IsAttached = false;
                _package.Ui.Update();
            }

            return(VSConstants.S_OK);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            //
            // Custom event handler.
            //

            LoggingUtils.PrintFunction();

            try
            {
                JavaLangDebuggerEventDelegate eventCallback;

                LoggingUtils.Print("[JavaLangDebuggerCallback] Event: " + riidEvent.ToString());

                if (!m_debuggerCallback.TryGetValue(riidEvent, out eventCallback))
                {
                    return(Constants.E_NOTIMPL);
                }

                LoggingUtils.RequireOk(eventCallback(m_debugEngine.JavaDebugger));

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

                return(Constants.E_FAIL);
            }
        }
Exemple #7
0
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            try
            {
                if (pProcess != null)
                {
                    // Check for an enter or exit event
                    if (riidEvent == typeof(IDebugExceptionEvent2).GUID)
                    {
                        ExtractExceptionDetails(pEvent);
                    }
                }
            }
            finally
            {
                // Unfortunately, these objects need to be released to avoid possible future dead locks if these are DCOM objects
                // and the process hosting the DCOM object goes away.
                var parametersForCleanup = new object[] { pEngine, pProcess, pProgram, pThread, pEvent };

                foreach (object parameter in parametersForCleanup)
                {
                    if (parameter != null && Marshal.IsComObject(parameter))
                    {
                        Marshal.ReleaseComObject(parameter);
                    }
                }
            }

            return(VSConstants.S_OK);
        }
        /// <summary>
        ///     Sends notification of debugging events to the SDM.
        /// </summary>
        /// <param name="engine">
        ///     An IDebugEngine2 object that represents the debug engine (DE) that is sending this event. A DE is
        ///     required to fill out this parameter.
        /// </param>
        /// <param name="process">
        ///     An IDebugProcess2 object that represents the process in which the event occurs. This parameter is
        ///     filled in by the session debug manager (SDM). A DE always passes a null value for this parameter.
        /// </param>
        /// <param name="program">
        ///     An IDebugProgram2 object that represents the program in which this event occurs. For most events,
        ///     this parameter is not a null value.
        /// </param>
        /// <param name="thread">
        ///     An IDebugThread2 object that represents the thread in which this event occurs. For stopping
        ///     events, this parameter cannot be a null value as the stack frame is obtained from this parameter.
        /// </param>
        /// <param name="event">An IDebugEvent2 object that represents the debug event.</param>
        /// <param name="riidEvent">GUID that identifies which event interface to obtain from the pEvent parameter.</param>
        /// <param name="attribs">A combination of flags from the EVENTATTRIBUTES enumeration.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program,
                         IDebugThread2 thread, IDebugEvent2 @event, ref Guid riidEvent, uint attribs)
        {
            var ad7EventCallback = GetAd7EventCallback();

            return(ad7EventCallback.Event(engine, process, program, thread, @event, ref riidEvent, attribs));
        }
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, 
			IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
        {
            if (!(debugEvent is IDebugProcessCreateEvent2) &&
                !(debugEvent is IDebugProcessDestroyEvent2))
                return VSConstants.S_OK;

            var target = GetTargetFromProcess(process);
            if (target == null)
            {
                _package.Reporter.ReportWarning("Can't find target from process {0} ({1}). Event: {2}.",
                    process.GetName(), process.GetProcessId(), TypeHelper.GetDebugEventTypeName(debugEvent));
                return VSConstants.S_OK;
            }

            if (debugEvent is IDebugProcessCreateEvent2)
            {
                target.IsAttached = true;
                _package.History.Items.AddFirst(target);
                _package.Ui.Update();
            }
            else
            {
                target.IsAttached = false;
                _package.Ui.Update();
            }

            return VSConstants.S_OK;
        }
Exemple #10
0
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            if (riidEvent == typeof(IDebugProgramCreateEvent2).GUID)
            {
                Guid processId;

                // A program was created and attached
                if (pProcess != null)
                {
                    if (VSConstants.S_OK == pProcess.GetProcessId(out processId))
                    {
                        DkmProcess dkmProcess = DkmProcess.FindProcess(processId);

                        if (dkmProcess != null)
                        {
                            var debugTrigger  = DkmExceptionCodeTrigger.Create(DkmExceptionProcessingStage.Thrown, null, DkmExceptionCategory.Win32, RemoteDebugStartExceptionCode);
                            var attachTrigger = DkmExceptionCodeTrigger.Create(DkmExceptionProcessingStage.Thrown, null, DkmExceptionCategory.Win32, RemoteDebugAttachExceptionCode);

                            // Try to add exception trigger for when a remote debugger server is started for Python
                            dkmProcess.AddExceptionTrigger(RemoteDebugExceptionGuid, debugTrigger);
                            dkmProcess.AddExceptionTrigger(RemoteDebugExceptionGuid, attachTrigger);
                        }
                    }
                }
            }

            return(VSConstants.S_OK);
        }
Exemple #11
0
        // TODO: Evaluate if this is still necessary
        //private void WarnAboutPGO(string moduleName) {
        //    const string content =
        //        "Python/native mixed-mode debugging does not support Python interpreters that are built with PGO (profile-guided optimization) enabled. " +
        //        "If you are using a stock Python interpreter, you should upgrade to a more recent version of it. If you're using a custom built " +
        //        "interpreter, please disable PGO.";
        //    MessageBox.Show(content, "PGO Is Not Supported", MessageBoxButton.OK, MessageBoxImage.Error);
        //}

        private void SetDebugOptions(IDebugEngine2 engine)
        {
            var pyService = _serviceProvider.GetPythonToolsService();

            var options = new StringBuilder();

            if (pyService.DebuggerOptions.WaitOnAbnormalExit)
            {
                options.Append(";" + AD7Engine.WaitOnAbnormalExitSetting + "=True");
            }
            if (pyService.DebuggerOptions.WaitOnNormalExit)
            {
                options.Append(";" + AD7Engine.WaitOnNormalExitSetting + "=True");
            }
            if (pyService.DebuggerOptions.TeeStandardOutput)
            {
                options.Append(";" + AD7Engine.RedirectOutputSetting + "=True");
            }
            if (pyService.DebuggerOptions.BreakOnSystemExitZero)
            {
                options.Append(";" + AD7Engine.BreakSystemExitZero + "=True");
            }
            if (pyService.DebuggerOptions.DebugStdLib)
            {
                options.Append(";" + AD7Engine.DebugStdLib + "=True");
            }

            engine.SetMetric(AD7Engine.DebugOptionsMetric, options.ToString());
        }
 public DebugEngineHandler(JoinableTaskContext taskContext, IDebugEngine2 debugEngine,
                           IDebugEventCallback2 eventCallback)
 {
     _taskContext   = taskContext;
     _debugEngine   = debugEngine;
     _eventCallback = eventCallback;
 }
Exemple #13
0
        public int Event(
            IDebugEngine2 pEngine,
            IDebugProcess2 pProcess,
            IDebugProgram2 pProgram,
            IDebugThread2 pThread,
            IDebugEvent2 pEvent,
            ref Guid riidEvent,
            uint dwAttrib
            )
        {
            if (riidEvent == typeof(IDebugProgramCreateEvent2).GUID)
            {
                RaiseStartEvent();
            }
            else if (riidEvent == typeof(IDebugMessageEvent2).GUID)
            {
                IDebugMessageEvent2 debugMessageEvent = pEvent as IDebugMessageEvent2;

                enum_MESSAGETYPE[] messageTypes = new enum_MESSAGETYPE[2];
                messageTypes[0] = enum_MESSAGETYPE.MT_OUTPUTSTRING;
                messageTypes[1] = enum_MESSAGETYPE.MT_REASON_TRACEPOINT;
                string message;
                uint   dwType;
                string helpFilename;
                uint   helpId;

                debugMessageEvent.GetMessage(messageTypes, out message, out dwType, out helpFilename, out helpId);

                // MessageEvents always have a \n on the end
                message = message.TrimEnd(Environment.NewLine.ToCharArray());

                RaiseDebugMessageEvent(message);
            }
            return(0);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public async Task <int> OnDebuggerLogcatEvent(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, Guid riidEvent, uint dwAttrib)
        {
            LoggingUtils.PrintFunction();

            try
            {
                DebugEngineEvent.DebuggerLogcatEvent debuggerLogcatEvent = pEvent as DebugEngineEvent.DebuggerLogcatEvent;

                using (SyncRedirectProcess command = AndroidAdb.AdbCommand(debuggerLogcatEvent.HostDevice, "logcat", "-c"))
                {
                    command.StartAndWaitForExit();
                }

                m_adbLogcatProcess = AndroidAdb.AdbCommandAsync(debuggerLogcatEvent.HostDevice, "logcat", "");

                m_adbLogcatListener = new DeviceLogcatListener();

                m_adbLogcatProcess.Start(m_adbLogcatListener);

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

                return(VSConstants.E_FAIL);
            }
        }
Exemple #15
0
        public static int Event(this IDebugEventCallback2 callback, IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, IDebugThread2 thread, DebugEvent debugEvent)
        {
            Contract.Requires <ArgumentNullException>(callback != null, "callback");
            Contract.Requires <ArgumentNullException>(debugEvent != null, "debugEvent");
            Contract.Requires <ArgumentNullException>(engine != null, "engine");

            return(callback.Event(engine, process, program, thread, debugEvent, debugEvent.EventGuid, (uint)debugEvent.Attributes));
        }
Exemple #16
0
 public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram,
                  IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
 {
     Trace.WriteLine($"VSFake: Received IDebugEvent2 {{type:\"{pEvent.GetType()}\", " +
                     $"interfaces:{GetInteropInterfacesTrace(pEvent)}}}");
     return(jobOrchestrator.HandleCallbackEvent(pEngine, pProcess, pProgram, pThread,
                                                pEvent));
 }
 /// <summary>
 /// Start the debugger using the given debug engine. This sends events to the SDM which
 /// tells it that we are ready to debug.
 /// </summary>
 public void Start(IDebugEngine2 debugEngine)
 {
     _listenerSubscriber.BreakpointChanged += OnBreakpointChanged;
     // The order of these two events is important!! Visual studio always needs to know that
     // the engine has been created before the program is created.
     _debugEngineHandler.SendEvent(new EngineCreateEvent(debugEngine), _debugProgram);
     _debugEngineHandler.SendEvent(new ProgramCreateEvent(), _debugProgram);
 }
        public static int Event(this IDebugEventCallback2 callback, IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, IDebugThread2 thread, DebugEvent debugEvent)
        {
            Contract.Requires<ArgumentNullException>(callback != null, "callback");
            Contract.Requires<ArgumentNullException>(debugEvent != null, "debugEvent");
            Contract.Requires<ArgumentNullException>(engine != null, "engine");

            return callback.Event(engine, process, program, thread, debugEvent, debugEvent.EventGuid, (uint)debugEvent.Attributes);
        }
 public ProgramStoppedJob(JoinableTaskContext taskContext, IDebugEngine2 debugEngine,
                          IDebugEvent2 evnt, IDebugSessionContext debugSessionContext, IDebugThread2 thread,
                          IFiredBreakpointSetter firedBreakpointSetter)
     : base(taskContext, debugEngine, evnt)
 {
     _debugSessionContext = debugSessionContext;
     _thread = thread;
     _firedBreakpointSetter = firedBreakpointSetter;
 }
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            if (pEvent is IRunspaceRequest)
            {
                var request = pEvent as IRunspaceRequest;
                request.SetRunspace(_runspace, _breakpoints);
            }

            return(VSConstants.S_OK);
        }
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            if (pEvent is IRunspaceRequest)
            {
                var request = pEvent as IRunspaceRequest;
                request.SetRunspace(_runspace, _breakpoints);
            }

            return VSConstants.S_OK;
        }
Exemple #22
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int OnError(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            //
            // IDebugErrorEvent2 is used to report error messages to the user when something goes wrong in the debug engine.
            //

            LoggingUtils.PrintFunction();

            return(Constants.E_NOTIMPL);
        }
 public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
 {
     if (riidEvent == new Guid("ce6f92d3-4222-4b1e-830d-3ecff112bf22"))
     {
         if (pThread != null)
         {
             this.m_Loader.DebugThread = pThread;
         }
     }
     return(0);
 }
        DebugPortNotify(IDebugEventCallback2 callback, IDebugEngine2 debugEngine,
                        DebugProgram.Factory debugProgramFactory, DefaultPort.Factory defaultPortFactory,
                        Process.Factory processFactory)
        {
            programNodes = new List <IDebugProgramNode2>();

            this.callback            = callback;
            this.debugEngine         = debugEngine;
            this.debugProgramFactory = debugProgramFactory;
            this.defaultPortFactory  = defaultPortFactory;
            this.processFactory      = processFactory;
        }
Exemple #25
0
        public int Event(IDebugEngine2 pEngine,
                         IDebugProcess2 pProcess,
                         IDebugProgram2 pProgram,
                         IDebugThread2 pThread,
                         IDebugEvent2 pEvent,
                         ref Guid riidEvent,
                         uint dwAttrib)
        {
            Logger.Debug(string.Empty);

            return(VSConstants.S_OK);
        }
        public int Event( IDebugEngine2 pEngine,
            IDebugProcess2 pProcess,
            IDebugProgram2 pProgram,
            IDebugThread2 pThread,
            IDebugEvent2 pEvent,
            ref Guid riidEvent,
            uint dwAttrib)
        {
            Logger.Debug( string.Empty );

            return VSConstants.S_OK;
        }
        public IDebugPort2 InitializePort(IDebugEventCallback2 callback, IDebugEngine2 debugEngine)
        {
            // When attaching to a core, the port and process come from our implementation of a
            // port supplier. if we are launching a new game, where does it come from?
            // I think this is a default port that handles all windows based processes.
            // https://docs.microsoft.com/en-us/visualstudio/extensibility/debugger/ports?view=vs-2017
            var portNotify = portNotifyFactory.Create(callback, debugEngine);
            var port       = defaultPortFactory.Create(portNotify);
            var process    = processFactory.Create("Default Process", port);

            port.SetProcess(process);
            return(port);
        }
        public void SetUp()
        {
            var taskContext = new JoinableTaskContext();

            logSpy = new LogSpy();
            logSpy.Attach();

            program     = Substitute.For <IGgpDebugProgram>();
            debugEngine = Substitute.For <IDebugEngine2>();
            callback    = Substitute.For <IDebugEventCallback2>();

            handler = new DebugEngineHandler(taskContext, debugEngine, callback);

            var idArg = Arg.Any <Guid>();

            program.GetProgramId(out idArg)
            .Returns(x =>
            {
                x[0] = programId;
                return(VSConstants.S_OK);
            });

            var nameArg = Arg.Any <string>();

            program.GetName(out nameArg)
            .Returns(x =>
            {
                x[0] = programName;
                return(VSConstants.S_OK);
            });

            thread = Substitute.For <IDebugThread>();

            var threadNameArg = Arg.Any <string>();

            thread.GetName(out threadNameArg)
            .Returns(x =>
            {
                x[0] = threadName;
                return(VSConstants.S_OK);
            });

            var threadIdArg = Arg.Any <uint>();

            thread.GetThreadId(out threadIdArg)
            .Returns(x =>
            {
                x[0] = threadId;
                return(VSConstants.S_OK);
            });
        }
Exemple #29
0
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram,
                         IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            _taskContext.ThrowIfNotOnMainThread();

            _logger.Trace($"Note right of VS: <IN> IDebugEventCallback2 {pEvent.GetType()}");

            var result = _callback.Event(pEngine, pProcess, pProgram, pThread, pEvent,
                                         ref riidEvent, dwAttrib);

            _logger.Trace($"Note right of VS: <OUT> IDebugEventCallback2 {pEvent.GetType()}");

            return(result);
        }
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            var outputString = pEvent as IDebugOutputStringEvent2;

            if (outputString != null)
            {
                string newDebugString;
                newDebugString = "";
                if (outputString.GetString(out newDebugString) == 0)
                {
                    ((TabbedLogControl)(base.Content)).ReceivedString(newDebugString);
                }
            }
            return(0);
        }
Exemple #31
0
 int IDebugEventCallback2.Event(
     IDebugEngine2 pEngine,
     IDebugProcess2 pProcess,
     IDebugProgram2 pProgram,
     IDebugThread2 pThread,
     IDebugEvent2 pEvent,
     ref Guid riidEvent,
     uint dwAttrib)
 {
     if (Callback == null)
     {
         return(VSConstants.S_OK);
     }
     return(Callback.Event(pEngine, pProcess,
                           pProgram, pThread, pEvent, ref riidEvent, dwAttrib));
 }
Exemple #32
0
        int IDebugEventCallback2.Event(
            IDebugEngine2 pEngine,
            IDebugProcess2 pProcess,
            IDebugProgram2 pProgram,
            IDebugThread2 pThread,
            IDebugEvent2 pEvent,
            ref Guid riidEvent,
            uint dwAttrib)
        {
            if (pEngine == Engine)
            {
                return(VSConstants.S_OK);
            }

            if (pProcess == null && pProgram == null)
            {
                return(VSConstants.S_OK);
            }

            if (pProcess == null)
            {
                if (pProgram.GetProcess(out pProcess) != VSConstants.S_OK || pProcess == null)
                {
                    return(VSConstants.S_OK);
                }
            }

            var pProcessId = new AD_PROCESS_ID[1];

            if (pProcess.GetPhysicalProcessId(pProcessId) != VSConstants.S_OK)
            {
                return(VSConstants.S_OK);
            }

            if (pProcessId[0].dwProcessId != NativeProcId)
            {
                return(VSConstants.S_OK);
            }

            if (riidEvent == typeof(IDebugProgramDestroyEvent2).GUID)
            {
                TerminateProcess();
            }

            return(VSConstants.S_OK);
        }
Exemple #33
0
    public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
        if (pEvent is IDebugProgramDestroyEvent2)
        {
            // The process has exited

            uint exitCode;
            if (((IDebugProgramDestroyEvent2)pEvent).GetExitCode(out exitCode) == VSConstants.S_OK)
            {
                // We got the exit code!
            }

            // Stop listening for future exit events
            _debugger.UnadviseDebugEventCallback(this);
            _debugger = null;
        }
        return(VSConstants.S_OK);
    }
Exemple #34
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int OnDebuggerConnectionEvent(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            LoggingUtils.PrintFunction();

            try
            {
                DebugEngineEvent.DebuggerConnectionEvent debuggerConnectionEvent = pEvent as DebugEngineEvent.DebuggerConnectionEvent;

                switch (debuggerConnectionEvent.Type)
                {
                case DebugEngineEvent.DebuggerConnectionEvent.EventType.ShowDialog:
                {
                    LoggingUtils.RequireOk(m_debuggerConnectionService.LaunchDialogShow());

                    break;
                }

                case DebugEngineEvent.DebuggerConnectionEvent.EventType.CloseDialog:
                {
                    LoggingUtils.RequireOk(m_debuggerConnectionService.LaunchDialogClose());

                    break;
                }

                case DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus:
                case DebugEngineEvent.DebuggerConnectionEvent.EventType.LogError:
                {
                    bool isError = (debuggerConnectionEvent.Type == DebugEngineEvent.DebuggerConnectionEvent.EventType.LogError);

                    LoggingUtils.RequireOk(m_debuggerConnectionService.LaunchDialogUpdate(debuggerConnectionEvent.Message, isError));

                    break;
                }
                }

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

                return(VSConstants.E_FAIL);
            }
        }
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program,
            IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
        {
            if (process == null)
                return VSConstants.S_OK;
            string processName;
            if (process.GetName((uint) enum_GETNAME_TYPE.GN_FILENAME, out processName) != VSConstants.S_OK)
                return VSConstants.S_OK;
            if (processName.EndsWith("vshost.exe"))
                return VSConstants.S_OK;

            var shortName = Path.GetFileName(processName);

            if (debugEvent is IDebugProcessCreateEvent2)
            {
                Log.Instance.SetStatus("[attaching...] {0}", shortName);
                Storage.Instance.SubscribeProcess(processName);
            }
            if (debugEvent is IDebugProcessDestroyEvent2)
            {
                Log.Instance.SetStatus("[detached] {0}", shortName);
                Log.Instance.AppendLine("[detached] {0}", shortName);
            }
            if (debugEvent is  IDebugLoadCompleteEvent2)
            {
                if (program != null)
                {
                    string engineName;
                    Guid engineId;
                    if (program.GetEngineInfo(out engineName, out engineId) == VSConstants.S_OK)
                    {
                        var fields = new PROCESS_INFO[1];
                        if (process.GetInfo((uint)enum_PROCESS_INFO_FIELDS.PIF_PROCESS_ID, fields) != VSConstants.S_OK)
                            return VSConstants.S_OK;
                        Storage.Instance.SubscribeEngine(processName, engineId);
                        AttachCenter.Instance.Freeze();

                        Log.Instance.SetStatus("[attached] {0}", shortName);
                        Log.Instance.AppendLine("[attached] {0} ({1}) / {2}", shortName, fields[0].ProcessId.dwProcessId, engineName);
                    }
                }
            }
            return VSConstants.S_OK;
        }
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program,
            IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
        {
            // Ignore a few events right away.
            if (debugEvent is IDebugModuleLoadEvent2 ||
                debugEvent is IDebugThreadCreateEvent2 ||
                debugEvent is IDebugThreadDestroyEvent2)
                return VSConstants.S_OK;

            if (process == null)
                return VSConstants.S_OK;

            if (debugEvent is IDebugProcessCreateEvent2) {
                State.IsAttached = true;
            }
            else if (debugEvent is IDebugProcessDestroyEvent2) {
                State.IsAttached = false;
            }

            return VSConstants.S_OK;
        }
Exemple #37
0
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, 
			IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
        {
            // Ignore a few events right away.
            if (debugEvent is IDebugModuleLoadEvent2 ||
                debugEvent is IDebugThreadCreateEvent2 ||
                debugEvent is IDebugThreadDestroyEvent2)
                return VSConstants.S_OK;

            // Trace.WriteLine(TypeHelper.GetDebugEventTypeName(debugEvent)); // TODO: Remove me.

            if (process == null)
                return VSConstants.S_OK;

            var target = GetTargetFromProcess(process);

            if (target == null)
            {
                _package.Reporter.ReportWarning("Can't find target from process {0} ({1}). Event: {2}.",
                    process.GetName(), process.GetProcessId(), TypeHelper.GetDebugEventTypeName(debugEvent));
                return VSConstants.S_OK;
            }
            if (debugEvent is IDebugProcessCreateEvent2)
            {
                target.IsAttached = true;
                _package.History.Items.AddFirst(target);
                _package.Ui.Update();
                return VSConstants.S_OK;
            }

            if (debugEvent is IDebugProcessDestroyEvent2)
            {
                target.IsAttached = false;
                _package.Ui.Update();
                return VSConstants.S_OK;
            }

            return VSConstants.S_OK;
        }
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
        {
            if (riidEvent == typeof(IDebugOutputStringEvent2).GUID)
            {
                IDebugOutputStringEvent2 ev = pEvent as IDebugOutputStringEvent2;
                if (ev != null)
                {
                    string message;
                    if (ErrorHandler.Succeeded(ev.GetString(out message)))
                    {
                        var lines = message.Split(sp, StringSplitOptions.RemoveEmptyEntries);

                        foreach(var line in lines)
                        {
                            HandleMessage(line);
                        }
                    }
                }
            }

            return VSConstants.S_OK;
        }
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, 
			IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes)
        {
            // _package.Reporter.ReportTrace(TypeHelper.GetDebugEventTypeName(debugEvent));

            if (!(debugEvent is IDebugProcessCreateEvent2) &&
                !(debugEvent is IDebugProcessDestroyEvent2))
                return VSConstants.S_OK;

            var target = GetTargetFromProcess(process);
            if (target == null)
            {
                _package.Reporter.ReportWarning("Can't find target from process {0} ({1}). Event: {2}.",
                    process.GetName(), process.GetProcessId(), TypeHelper.GetDebugEventTypeName(debugEvent));
                return VSConstants.S_OK;
            }

            if (debugEvent is IDebugProcessCreateEvent2)
            {
                var engines = target.Engines.Where(e => _engines.ContainsKey(e)).Select(e => _engines[e]).ToArray();

                var mode = new DBGMODE[1];
                _debugger.GetMode(mode);
                if (mode[0] == DBGMODE.DBGMODE_Design)
                    return VSConstants.S_OK;

                target.IsAttached = true;
                _package.History.Items.AddFirst(target);
                _package.Ui.Update();
            }
            else
            {
                target.IsAttached = false;
                _package.Ui.Update();
            }

            return VSConstants.S_OK;
        }
        public int Event(IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib) {
            if (riidEvent == typeof(IDebugProgramCreateEvent2).GUID) {
                Guid processId;

                // A program was created and attached
                if (pProcess != null) {
                    if (VSConstants.S_OK == pProcess.GetProcessId(out processId)) {
                        DkmProcess dkmProcess = DkmProcess.FindProcess(processId);

                        if (dkmProcess != null) {
                            var debugTrigger = DkmExceptionCodeTrigger.Create(DkmExceptionProcessingStage.Thrown, null, DkmExceptionCategory.Win32, RemoteDebugStartExceptionCode);
                            var attachTrigger = DkmExceptionCodeTrigger.Create(DkmExceptionProcessingStage.Thrown, null, DkmExceptionCategory.Win32, RemoteDebugAttachExceptionCode);

                            // Try to add exception trigger for when a remote debugger server is started for Python
                            dkmProcess.AddExceptionTrigger(RemoteDebugExceptionGuid, debugTrigger);
                            dkmProcess.AddExceptionTrigger(RemoteDebugExceptionGuid, attachTrigger);
                        }
                    }
                }
            }

            return VSConstants.S_OK;
        }
Exemple #41
0
        int IDebugEngineCreateEvent2.GetEngine(out IDebugEngine2 engine)
        {
            engine = m_engine;

            return VSConstants.S_OK;
        }
Exemple #42
0
 AD7EngineCreateEvent(AD7Engine engine)
 {
     m_engine = engine;
 }
Exemple #43
0
 //private AD7EngineCreateEvent(AD7Engine engine)
 public AD7EngineCreateEvent(AD7Engine engine)
 {
     _engine = engine;
 }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int OnError (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        DebugEngineEvent.Error errorEvent = pEvent as DebugEngineEvent.Error;

        enum_MESSAGETYPE [] messageType = new enum_MESSAGETYPE [1];

        string errorFormat, errorHelpFileName;

        int errorReason;

        uint errorType, errorHelpId;

        LoggingUtils.RequireOk (errorEvent.GetErrorMessage (messageType, out errorFormat, out errorReason, out errorType, out errorHelpFileName, out errorHelpId));

        LoggingUtils.RequireOk (m_debuggerConnectionService.LaunchDialogUpdate (errorFormat, true));

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

        return VSConstants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #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;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int Event (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      // 
      // Custom event handler.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        JavaLangDebuggerEventDelegate eventCallback;

        LoggingUtils.Print ("[JavaLangDebuggerCallback] Event: " + riidEvent.ToString ());

        if (!m_debuggerCallback.TryGetValue (riidEvent, out eventCallback))
        {
          return Constants.E_NOTIMPL;
        }

        LoggingUtils.RequireOk (eventCallback (m_debugEngine.JavaDebugger));

        return Constants.S_OK;

      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        return Constants.E_FAIL;
      }
    }
Exemple #47
0
 private AD7EngineCreateEvent(AD7Engine engine)
 {
     _engine = engine;
 }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int OnError (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      // 
      // IDebugErrorEvent2 is used to report error messages to the user when something goes wrong in the debug engine.
      // 

      LoggingUtils.PrintFunction ();

      return Constants.E_NOTIMPL;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int OnDebuggerConnectionEvent (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        DebugEngineEvent.DebuggerConnectionEvent debuggerConnectionEvent = pEvent as DebugEngineEvent.DebuggerConnectionEvent;

        switch (debuggerConnectionEvent.Type)
        {
          case DebugEngineEvent.DebuggerConnectionEvent.EventType.ShowDialog:
          {
            LoggingUtils.RequireOk (m_debuggerConnectionService.LaunchDialogShow ());

            break;
          }

          case DebugEngineEvent.DebuggerConnectionEvent.EventType.CloseDialog:
          {
            LoggingUtils.RequireOk (m_debuggerConnectionService.LaunchDialogClose ());

            break;
          }

          case DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus:
          case DebugEngineEvent.DebuggerConnectionEvent.EventType.LogError:
          {
            bool isError = (debuggerConnectionEvent.Type == DebugEngineEvent.DebuggerConnectionEvent.EventType.LogError);

            LoggingUtils.RequireOk (m_debuggerConnectionService.LaunchDialogUpdate (debuggerConnectionEvent.Message, isError));

            break;
          }
        }

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

        return VSConstants.E_FAIL;
      }
    }
 int IDebugEventCallback2.Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, IDebugThread2 thread, IDebugEvent2 @event, ref Guid riidEvent, uint attribs)
 {
     IDebugEventCallback2 ad7EventCallback = GetAD7EventCallback();
     return ad7EventCallback.Event(engine, process, program, thread, @event, ref riidEvent, attribs);
 }
        // TODO: Evaluate if this is still necessary
        //private void WarnAboutPGO(string moduleName) {
        //    const string content =
        //        "Python/native mixed-mode debugging does not support Python interpreters that are built with PGO (profile-guided optimization) enabled. " +
        //        "If you are using a stock Python interpreter, you should upgrade to a more recent version of it. If you're using a custom built " +
        //        "interpreter, please disable PGO.";
        //    MessageBox.Show(content, "PGO Is Not Supported", MessageBoxButton.OK, MessageBoxImage.Error);
        //}

        private void SetDebugOptions(IDebugEngine2 engine) {
            var pyService = _serviceProvider.GetPythonToolsService();

            var options = new StringBuilder();
            if (pyService.DebuggerOptions.WaitOnAbnormalExit) {
                options.Append(";" + AD7Engine.WaitOnAbnormalExitSetting + "=True");
            }
            if (pyService.DebuggerOptions.WaitOnNormalExit) {
                options.Append(";" + AD7Engine.WaitOnNormalExitSetting + "=True");
            }
            if (pyService.DebuggerOptions.TeeStandardOutput) {
                options.Append(";" + AD7Engine.RedirectOutputSetting + "=True");
            }
            if (pyService.DebuggerOptions.BreakOnSystemExitZero) {
                options.Append(";" + AD7Engine.BreakSystemExitZero + "=True");
            }
            if (pyService.DebuggerOptions.DebugStdLib) {
                options.Append(";" + AD7Engine.DebugStdLib + "=True");
            }

            engine.SetMetric(AD7Engine.DebugOptionsMetric, options.ToString());
        }
 public AD7Events(IDebugEngine2 engine, IDebugEventCallback2 callback)
 {
   _engine = engine;
   _callback = callback;
 }
 public DebugEntryPointEvent(IDebugEngine2 mEngine)
 {
   Engine = mEngine;
 }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int OnProgramCreate (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        /*DebuggeeProgram p = pProgram as DebuggeeProgram;

        bool worked = false;

        if (pProgram is DebuggeeProgram)
        {
          worked = true;
        }

        Type t = pProgram.GetType ();

        IntPtr pUnk = Marshal.GetIUnknownForObject (pProgram);

        Guid guidDebuggeeProgram = ComUtils.GuidOf (typeof (IDebugProgram2));

        IDebugProgram2 debuggeeProgramObj = (IDebugProgram2) Marshal.GetTypedObjectForIUnknown (pUnk, typeof (IDebugProgram2));

        DebuggeeProgram debuggeeProgram = debuggeeProgramObj as DebuggeeProgram;

        debuggeeProgram = (DebuggeeProgram) Marshal.CreateWrapperOfType (debuggeeProgramObj, typeof (IDebugProgram2));
        */

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

        return VSConstants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #endregion

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

    #region IDebugEventCallback2 Members

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

    public int Event (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      try
      {
        DebuggerEventListenerDelegate callback;

        LoggingUtils.Print ("[DebuggerEventListener] Event: " + riidEvent.ToString ());

        int handle = VsDebugCommon.Constants.E_NOTIMPL;

        if (!m_eventCallbacks.TryGetValue (riidEvent, out callback))
        {
          return handle;
        }

        handle = callback (pEngine, pProcess, pProgram, pThread, pEvent, ref riidEvent, dwAttrib);

        if (handle != VsDebugCommon.Constants.E_NOTIMPL)
        {
          LoggingUtils.RequireOk (handle);
        }

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

        return VSConstants.E_FAIL;
      }
    }
 public EngineCreate (IDebugEngine2 engine)
 {
   m_engine = engine;
 }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int Event (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      // 
      // Custom event handler.
      // 

      try
      {
        LoggingUtils.Print ("[CLangDebuggerCallback] Event: " + riidEvent.ToString ());

        CLangDebuggerEventDelegate eventCallback;

        if (!m_debuggerCallback.TryGetValue (riidEvent, out eventCallback))
        {
          return Constants.E_NOTIMPL;
        }

        return eventCallback (m_debugEngine.NativeDebugger);
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

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

    public int OnDebuggerLogcatEvent (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        DebugEngineEvent.DebuggerLogcatEvent debuggerLogcatEvent = pEvent as DebugEngineEvent.DebuggerLogcatEvent;

        using (SyncRedirectProcess command = AndroidAdb.AdbCommand (debuggerLogcatEvent.HostDevice, "logcat", "-c"))
        {
          command.StartAndWaitForExit ();
        }

        m_adbLogcatProcess = AndroidAdb.AdbCommandAsync (debuggerLogcatEvent.HostDevice, "logcat", "");

        m_adbLogcatListener = new DeviceLogcatListener ();

        if (m_adbLogcatProcess == null)
        {
          throw new InvalidOperationException ("Failed to launch logcat application.");
        }

        if (m_adbLogcatListener == null)
        {
          throw new InvalidOperationException ("Failed to launch logcat listener.");
        }

        m_adbLogcatProcess.Start (m_adbLogcatListener);

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

        return VSConstants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int OnProgramDestroy (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        if (m_adbLogcatProcess != null)
        {
          m_adbLogcatProcess.Kill ();

          m_adbLogcatProcess.Dispose ();

          m_adbLogcatProcess = null;
        }

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

        return VSConstants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int OnThreadDestroy (IDebugEngine2 pEngine, IDebugProcess2 pProcess, IDebugProgram2 pProgram, IDebugThread2 pThread, IDebugEvent2 pEvent, ref Guid riidEvent, uint dwAttrib)
    {
      LoggingUtils.PrintFunction ();

      return Constants.E_NOTIMPL;
    }