예제 #1
0
파일: AD7Engine.cs 프로젝트: e42s/VSLua
        // Attach the debug engine to a program. 
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            int processId = EngineUtils.GetProcessId(rgpPrograms[0]);
            if (processId == 0)
            {
                return VSConstants.E_NOTIMPL;
            }

            pID = (uint)processId;

            events = ad7Callback;

            EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_ad7ProgramId));

            AD7EngineCreateEvent.Send(this);

            AD7ProgramCreateEvent.Send(this);

            debugThread = new AD7Thread(this);

            AD7ThreadCreateEvent.Send(this);

            // This event is optional
            AD7LoadCompleteEvent.Send(this);
           

            return VSConstants.S_OK;
        }
예제 #2
0
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            if (celtPrograms == 0)
                return VSConstants.S_OK;

            if (pCallback == null)
                throw new ArgumentNullException("pCallback");
            if (rgpPrograms == null || rgpPrograms.Length < celtPrograms)
                throw new ArgumentException();
            if (rgpProgramNodes == null || rgpProgramNodes.Length < celtPrograms)
                throw new ArgumentException();

            if (celtPrograms > 1)
                throw new NotImplementedException();

            if (dwReason != enum_ATTACH_REASON.ATTACH_REASON_LAUNCH)
                throw new NotImplementedException();

            JavaDebugProgram program = rgpProgramNodes[0] as JavaDebugProgram;
            if (program == null)
                throw new NotSupportedException();

            lock (_programs)
            {
                _programs.Add(program);
            }

            DebugEvent @event = new DebugEngineCreateEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS, this);
            pCallback.Event(this, program.GetProcess(), program, null, @event);

            program.InitializeDebuggerChannel(this, pCallback);
            return VSConstants.S_OK;
        }
        /// <summary>
        ///     Attaches to the specified program nodes. This is the main entry point to debugging.
        /// </summary>
        /// <remarks>
        ///     This method is responsible for firing the correct Visual Studio events to begin debugging
        ///     and then to start the actual PowerShell execution.
        /// </remarks>
        /// <param name="rgpPrograms">The programs.</param>
        /// <param name="rgpProgramNodes">The program nodes.</param>
        /// <param name="celtPrograms">The celt programs.</param>
        /// <param name="pCallback">The callback.</param>
        /// <param name="dwReason">The reason.</param>
        /// <returns></returns>
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms,
                          IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            Log.Debug("Attaching the debug engine.");

            Guid id;

            rgpPrograms[0].GetProgramId(out id);

            if (_node == null)
            {
                _node = rgpProgramNodes[0] as ScriptProgramNode;
                _node.IsAttachedProgram = dwReason == enum_ATTACH_REASON.ATTACH_REASON_USER;
            }

            _node.Id = id;

            var publisher = (IDebugProgramPublisher2) new DebugProgramPublisher();

            publisher.PublishProgramNode(_node);

            _events = new EngineEvents(this, pCallback);
            _events.RunspaceRequest();
            _events.EngineCreated();
            _events.ProgramCreated(_node);
            _events.EngineLoaded();

            _events.DebugEntryPoint();

            Task.Factory.StartNew(Execute);

            return(VSConstants.S_OK);
        }
예제 #4
0
        int IDebugEngine2.Attach(
            IDebugProgram2[] rgpPrograms,
            IDebugProgramNode2[] rgpProgramNodes,
            uint celtPrograms,
            IDebugEventCallback2 pCallback,
            enum_ATTACH_REASON dwReason)
        {
            var program = rgpProgramNodes[0] as Program;

            if (program == null)
            {
                return(VSConstants.E_FAIL);
            }

            Callback = pCallback;

            DebugEvent.Send(new EngineCreateEvent(this));

            if (rgpPrograms[0].GetProgramId(out Guid pguidProgramId) != VSConstants.S_OK)
            {
                return(VSConstants.E_FAIL);
            }

            program.ProgramId = pguidProgramId;

            DebugEvent.Send(new ProgramCreateEvent(program));
            DebugEvent.Send(new ThreadCreateEvent(program));
            DebugEvent.Send(new LoadCompleteEvent(program));
            DebugEvent.Send(new EntryPointEvent(program));

            program.OutputWriteLine("Connecting to the QML runtime...");

            return(VSConstants.S_OK);
        }
        public void AttachNeedsNumProgramsToEqual1([Values] enum_ATTACH_REASON attachReason)
        {
            IGgpDebugEngine debugEngine = CreateGgpDebugEngine();

            int result = debugEngine.Attach(null, null, 2, null, attachReason);

            Assert.That(result, Is.EqualTo(VSConstants.E_INVALIDARG));
        }
예제 #6
0
 /// <summary>
 /// Attaches a debug DebugEngine (DE) to a program or programs. Called by the session debug manager (SDM) when the DE is running in-process to the SDM.
 /// </summary>
 /// <param name="rgpPrograms">An array of IDebugProgram2 objects that represent programs to be attached to. These are port programs.</param>
 /// <param name="rgpProgramNodes">An array of IDebugProgramNode2 objects that represent program nodes, one for each program. The program nodes in this array represent the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to.</param>
 /// <param name="celtPrograms">Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays.</param>
 /// <param name="pCallback">The IDebugEventCallback2 object to be used to send debug events to the SDM.</param>
 /// <param name="dwReason">A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. For more information, see the Remarks section.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 /// <remarks>
 /// There are three reasons for attaching to a program, as follows:
 ///     ATTACH_REASON_LAUNCH indicates that the DE is attaching to the program because the user launched the process that contains it.
 ///     ATTACH_REASON_USER indicates that the user has explicitly requested the DE to attach to a program (or the process that contains a program).
 ///     ATTACH_REASON_AUTO indicates the DE is attaching to a particular program because it is already debugging other programs in a particular process. This is also called auto-attach
 ///
 /// When this method is called, the DE needs to send these events in sequence:
 ///     IDebugEngineCreateEvent2 (if it has not already been sent for a particular instance of the debug DebugEngine)
 ///     IDebugProgramCreateEvent2
 ///     IDebugLoadCompleteEvent2
 ///
 /// In addition, if the reason for attaching is ATTACH_REASON_LAUNCH, the DE needs to send the IDebugEntryPointEvent2 event.
 /// Once the DE gets the IDebugProgramNode2 object corresponding to the program being debugged, it can be queried for any private interface.
 /// Before calling the methods of a program node in the array given by pProgram or rgpProgramNodes, impersonation, if required, should be enabled on the IDebugProgram2 interface that represents the program node. Normally, however, this step is not necessary. For more information, see Security Issues.
 /// </remarks>
 public virtual int Attach(IDebugProgram2[] rgpPrograms,
                           IDebugProgramNode2[] rgpProgramNodes,
                           uint celtPrograms,
                           IDebugEventCallback2 pCallback,
                           enum_ATTACH_REASON dwReason)
 {
     Logger.Debug(string.Empty);
     return(VSConstants.E_NOTIMPL);
 }
예제 #7
0
 /// <summary>
 /// Attaches a debug DebugEngine (DE) to a program or programs. Called by the session debug manager (SDM) when the DE is running in-process to the SDM.
 /// </summary>
 /// <param name="rgpPrograms">An array of IDebugProgram2 objects that represent programs to be attached to. These are port programs.</param>
 /// <param name="rgpProgramNodes">An array of IDebugProgramNode2 objects that represent program nodes, one for each program. The program nodes in this array represent the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to.</param>
 /// <param name="celtPrograms">Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays.</param>
 /// <param name="pCallback">The IDebugEventCallback2 object to be used to send debug events to the SDM.</param>
 /// <param name="dwReason">A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. For more information, see the Remarks section.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 /// <remarks>
 /// There are three reasons for attaching to a program, as follows:
 ///     ATTACH_REASON_LAUNCH indicates that the DE is attaching to the program because the user launched the process that contains it.
 ///     ATTACH_REASON_USER indicates that the user has explicitly requested the DE to attach to a program (or the process that contains a program).
 ///     ATTACH_REASON_AUTO indicates the DE is attaching to a particular program because it is already debugging other programs in a particular process. This is also called auto-attach
 /// 
 /// When this method is called, the DE needs to send these events in sequence:
 ///     IDebugEngineCreateEvent2 (if it has not already been sent for a particular instance of the debug DebugEngine)
 ///     IDebugProgramCreateEvent2
 ///     IDebugLoadCompleteEvent2
 /// 
 /// In addition, if the reason for attaching is ATTACH_REASON_LAUNCH, the DE needs to send the IDebugEntryPointEvent2 event.
 /// Once the DE gets the IDebugProgramNode2 object corresponding to the program being debugged, it can be queried for any private interface.
 /// Before calling the methods of a program node in the array given by pProgram or rgpProgramNodes, impersonation, if required, should be enabled on the IDebugProgram2 interface that represents the program node. Normally, however, this step is not necessary. For more information, see Security Issues.
 /// </remarks>
 public virtual int Attach( IDebugProgram2[] rgpPrograms,
     IDebugProgramNode2[] rgpProgramNodes,
     uint celtPrograms,
     IDebugEventCallback2 pCallback,
     enum_ATTACH_REASON dwReason)
 {
     Logger.Debug( string.Empty );
     return VSConstants.E_NOTIMPL;
 }
예제 #8
0
    int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
    {
      Debug.WriteLine("AD7Engine Attach");
      Guid id;

      if (( DebuggerManager.Instance != null ) && ( DebuggerManager.Instance.Debugger.IsRunning))
      {
        // If already running, abort.
        MessageBox.Show("Cannot start MySql Debugger. A MySql Debug session is already running", "Error");
        return HRESULT.E_ATTACH_FAILED_ABORT_SILENTLY;
      }

      rgpPrograms[0].GetProgramId(out id);
      if (id == Guid.Empty)
      {
        return VSConstants.E_NOTIMPL;
      }

      _events = new AD7Events(this, pCallback);

      try
      {
        DebuggerManager.Init(_events, _node, _breakpoint);
      }
      catch (Exception ex)
      {
        MessageBox.Show(_node.ParentWindow, ex.GetBaseException().Message, "Debugger Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        return HRESULT.E_ATTACH_FAILED_ABORT_SILENTLY;
      }

      System.Threading.Thread thread = new System.Threading.Thread(() =>
      {
        DebuggerManager debugger = DebuggerManager.Instance;
        _node.Debugger = debugger;
        debugger.SteppingType = SteppingTypeEnum.StepInto;
        debugger.Breakpoint = new AD7Breakpoint(_node, _events);
        debugger.OnEndDebugger += () => { _events.ProgramDestroyed(_node); };
        debugger.Debugger.RestoreAtExit = true;
        debugger.Run();
      });
      thread.SetApartmentState(System.Threading.ApartmentState.STA);
      thread.Start();

      _node.Id = id;
      _events.EngineCreated();
      _events.ProgramCreated(_node);
      _events.EngineLoaded();
      _events.DebugEntryPoint();

      return VSConstants.S_OK;
    }
예제 #9
0
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms,
            IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            DebugHelper.TraceEnteringMethod();

            rgpPrograms[0].GetProgramId(out _programId);
            _dispatcher.Queue(() => DebuggedProcess.Attach());
            _dispatcher.Queue(() => DebuggedProcess.WaitForAttach());

            Events.EngineCreated();
            Events.ProgramCreated();

            return VSConstants.S_OK;
        }
예제 #10
0
 /// <summary>
 ///     Attach the debug engine to a program.
 /// </summary>
 /// <param name="programs"></param>
 /// <param name="rgpProgramNodes">.</param>
 /// <param name="celtPrograms"></param>
 /// <param name="pCallback"></param>
 /// <param name="dwReason"></param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms,
                   IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
 {
     try
     {
         Program.Attach(programs[0]);
         return(S_OK);
     }
     catch (Exception e)
     {
         OnStartDebuggingFailed(e);
         return(E_FAIL);
     }
 }
예제 #11
0
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms,
                          IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            DebugHelper.TraceEnteringMethod();

            rgpPrograms[0].GetProgramId(out _programId);
            _dispatcher.Queue(() => DebuggedProcess.Attach());
            _dispatcher.Queue(() => DebuggedProcess.WaitForAttach());

            Events.EngineCreated();
            Events.ProgramCreated();


            return(VSConstants.S_OK);
        }
예제 #12
0
        /// <summary>
        /// Attaches a debug engine (DE) to a program or programs. Called by the session debug manager (SDM) when the DE is running in-process to the SDM.
        /// </summary>
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.Attach");

            // Save program
            program = rgpPrograms[0] as DebugProgram;
            if (program == null)
                return VSConstants.E_INVALIDARG;

            // Update program state
            CopyExceptionMapToProgramDelayed();

            //eventCallback.Send(process, new ProcessCreateEvent());
            eventCallback.Send(program, new ProgramCreateEvent());
            return VSConstants.S_OK;
        }
        /// <summary>
        /// Attaches a debug DebugEngine (DE) to a program or programs. Called by the session debug manager (SDM) when the DE is running in-process to the SDM.
        /// </summary>
        /// <param name="rgpPrograms">An array of IDebugProgram2 objects that represent programs to be attached to. These are port programs.</param>
        /// <param name="rgpProgramNodes">An array of IDebugProgramNode2 objects that represent program nodes, one for each program. The program nodes in this array represent the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to.</param>
        /// <param name="celtPrograms">Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays.</param>
        /// <param name="pCallback">The IDebugEventCallback2 object to be used to send debug events to the SDM.</param>
        /// <param name="dwReason">A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. For more information, see the Remarks section.</param>
        /// <returns>
        /// If successful, returns S_OK; otherwise, returns an error code.
        /// </returns>
        public override int Attach(IDebugProgram2[] rgpPrograms,
                                   IDebugProgramNode2[] rgpProgramNodes,
                                   uint celtPrograms,
                                   IDebugEventCallback2 pCallback,
                                   enum_ATTACH_REASON dwReason)
        {
            Logger.Debug(string.Empty);
            if (celtPrograms != 1)
            {
                Debug.Fail("PowerStudio Engine only expects to see one program in a process.");
                throw new ArgumentException("celtPrograms");
            }

            CreateOrInitializeEventSource(pCallback);
            Program = new PowerShellProgramNode(Process);

            EngineEventSource.OnDebugEngineCreate();
            EngineEventSource.OnProgramCreate(Program);
            EngineEventSource.OnLoadComplete();

            return(VSConstants.S_OK);
        }
        /// <summary>
        /// Attaches a debug DebugEngine (DE) to a program or programs. Called by the session debug manager (SDM) when the DE is running in-process to the SDM.
        /// </summary>
        /// <param name="rgpPrograms">An array of IDebugProgram2 objects that represent programs to be attached to. These are port programs.</param>
        /// <param name="rgpProgramNodes">An array of IDebugProgramNode2 objects that represent program nodes, one for each program. The program nodes in this array represent the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to.</param>
        /// <param name="celtPrograms">Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays.</param>
        /// <param name="pCallback">The IDebugEventCallback2 object to be used to send debug events to the SDM.</param>
        /// <param name="dwReason">A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. For more information, see the Remarks section.</param>
        /// <returns>
        /// If successful, returns S_OK; otherwise, returns an error code.
        /// </returns>
        public override int Attach( IDebugProgram2[] rgpPrograms,
            IDebugProgramNode2[] rgpProgramNodes,
            uint celtPrograms,
            IDebugEventCallback2 pCallback,
            enum_ATTACH_REASON dwReason)
        {
            Logger.Debug( string.Empty );
            if ( celtPrograms != 1 )
            {
                Debug.Fail( "PowerStudio Engine only expects to see one program in a process." );
                throw new ArgumentException( "celtPrograms" );
            }

            CreateOrInitializeEventSource( pCallback );
            Program = new PowerShellProgramNode( Process );

            EngineEventSource.OnDebugEngineCreate();
            EngineEventSource.OnProgramCreate( Program );
            EngineEventSource.OnLoadComplete();

            return VSConstants.S_OK;
        }
        public void RemoteDeployNotCalledDuringAttachToCore(enum_ATTACH_REASON attachReason)
        {
            var gamelet = new Gamelet {
                IpAddr = _gameletIp
            };
            var expectedTarget = new SshTarget(gamelet);
            IDebugSessionLauncher debugSessionLauncher =
                CreateConfiguredDebugSessionLauncher(expectedTarget, x => {
                var attachedProgram = Substitute.For <ILldbAttachedProgram>();
                return(Task.FromResult(attachedProgram));
            });

            IDebugSessionLauncherFactory debugSessionLauncherFactory =
                CreateDebugSessionLauncherFactory(debugSessionLauncher);
            int calls        = 0;
            var remoteDeploy = Substitute.For <IRemoteDeploy>();

            remoteDeploy.DeployLldbServerAsync(expectedTarget, Arg.Any <IAction>()).Returns(x => {
                calls++;
                return(Task.CompletedTask);
            });
            IGgpDebugEngine debugEngine =
                CreateGgpDebugEngine(debugSessionLauncherFactory, remoteDeploy);
            IDebugPort2 debugPort = CreateDebugPort(gamelet);
            string      options   = null;

            debugEngine.LaunchSuspended("", debugPort, _exePath, null, null, null, options,
                                        enum_LAUNCH_FLAGS.LAUNCH_DEBUG, 0, 0, 0, null,
                                        out IDebugProcess2 _);
            IDebugProgram2 program = CreateDebugProgram(debugPort);

            IDebugProgram2[] rgpPrograms = { program };
            var rgpProgramNodes          = new[] { Substitute.For <IDebugProgramNode2>() };

            debugEngine.Attach(rgpPrograms, rgpProgramNodes, _celtPrograms, null, attachReason);

            Assert.That(calls, Is.EqualTo(0));
        }
예제 #16
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.WriteLine("PythonEngine Attach Begin " + GetHashCode());

            AssertMainThread();
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1) {
                Debug.Fail("Python debugging only supports one program in a process");
                throw new ArgumentException();
            }

            var program = rgpPrograms[0];
            int processId = EngineUtils.GetProcessId(program);
            if (processId == 0) {
                // engine only supports system processes
                Debug.WriteLine("PythonEngine failed to get process id during attach");
                return VSConstants.E_NOTIMPL;
            }

            EngineUtils.RequireOk(program.GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null) {
                _events = ad7Callback;

                Send(new AD7CustomEvent(VsPackageMessage.SetDebugOptions, this), AD7CustomEvent.IID, null);

                // Check whether we're debugging Python alongside something else. If so, let Concord handle everything.
                if (!IsDebuggingPythonOnly(program)) {
                    _attached = true;
                    _mixedMode = true;
                    AD7EngineCreateEvent.Send(this);
                    AD7ProgramCreateEvent.Send(this);
                    AD7LoadCompleteEvent.Send(this);
                    Debug.WriteLine("PythonEngine Attach bailing out early - mixed-mode debugging");
                    return VSConstants.S_OK;
                }

                // Check if we're attaching remotely using the Python remote debugging transport
                var remoteProgram = program as PythonRemoteDebugProgram;
                try {
                    if (remoteProgram != null) {
                        var remotePort = remoteProgram.DebugProcess.DebugPort;

                        var uriBuilder = new UriBuilder(remotePort.Uri);
                        string query = uriBuilder.Query ?? "";
                        if (query.Length > 0) {
                            // Strip leading "?" - UriBuilder.Query getter returns it as part of the string, but the setter
                            // will automatically prepend it even if it was already there, producing a malformed query.
                            query = query.Substring(1);
                        }
                        query += "&" + DebugOptionsKey + "=" + _debugOptions;
                        uriBuilder.Query = query;

                        _process = PythonRemoteProcess.Attach(uriBuilder.Uri, true);
                    } else {
                        _process = PythonProcess.Attach(processId, _debugOptions);
                    }
                } catch (ConnectionException ex) {
                    MessageBox.Show("Failed to attach debugger:\r\n" + ex.Message, null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return VSConstants.E_FAIL;
                }

                AttachEvents(_process);
                _attached = true;
            } else {
                if (processId != _process.Id) {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return VSConstants.E_FAIL;
                }
            }

            AD7EngineCreateEvent.Send(this);

            lock (_syncLock) {
                _engineCreated = true;
                if (_isProgramCreateDelayed) {
                    _isProgramCreateDelayed = false;
                    SendProgramCreate();
                }
            }

            Debug.WriteLine("PythonEngine Attach returning S_OK");
            return VSConstants.S_OK;
        }
예제 #17
0
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    #region IDebugEngine2 Members

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

    public int Attach (IDebugProgram2 [] rgpPrograms, IDebugProgramNode2 [] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
    {
      // 
      // Attach the debug engine to a program.
      // 

      LoggingUtils.PrintFunction ();

      m_sdmCallback = new DebugEngineCallback (this, ad7Callback);

      m_cLangCallback = new CLangDebuggerCallback (this);

      m_javaLangCallback = new JavaLangDebuggerCallback (this);

      try
      {
        if ((rgpPrograms == null) || (rgpPrograms.Length == 0))
        {
          throw new ApplicationException ("Attach failed. No target process specified.");
        }

        if (celtPrograms > 1)
        {
          throw new ApplicationException ("Attach failed. Can not debug multiple target processes concurrently.");
        }

        if (Program != null)
        {
          throw new ApplicationException ("Attach failed. Already attached to " + Program.DebugProcess.NativeProcess.Name);
        }

        AndroidAdb.Refresh ();

        Program = rgpPrograms [0] as DebuggeeProgram;

        Program.AttachedEngine = this;

        Program.DebugProcess.NativeProcess.RefreshPackageInfo ();

        Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Starting GDB client...")), null, null);

        NativeDebugger = new CLangDebugger (this, m_launchConfiguration, Program);

        Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Starting JDB client...")), null, null);

        JavaDebugger = new JavaLangDebugger (this, Program);

        ThreadPool.QueueUserWorkItem (delegate (object obj)
        {
          // 
          // When this method is called, the DE needs to send these events in sequence:
          // 1. IDebugEngineCreate2
          // 2. IDebugProgramCreateEvent2
          // 3. IDebugLoadCompleteEvent2
          // 4. (if enum_ATTACH_REASON.ATTACH_REASON_LAUNCH), IDebugEntryPointEvent2
          // 

          try
          {
            Broadcast (new DebugEngineEvent.EngineCreate (this), Program, null);

            // 
            // Run a couple of tests which prevent the run-as tool from functioning properly:
            // 
            // 1) Test if this device/emulator is susceptible to a (usually 4.3 specific) run-as permissions bug.
            //      https://code.google.com/p/android/issues/detail?id=58373
            // 2) Test if the installed package is not declared 'debuggable'.
            // 

            AndroidDevice debuggingDevice = Program.DebugProcess.NativeProcess.HostDevice;

            string runasPackageFileList = debuggingDevice.Shell (string.Format ("run-as {0}", Program.DebugProcess.NativeProcess.Name), "ls -l");

            if (runasPackageFileList.Contains (string.Format ("run-as: Package '{0}' is unknown", Program.DebugProcess.NativeProcess.Name)))
            {
              throw new InvalidOperationException ("Can not debug native code on this device/emulator.\nMore info: https://code.google.com/p/android/issues/detail?id=58373");
            }
            else if (runasPackageFileList.Contains (string.Format ("run-as: Package '{0}' is not debuggable", Program.DebugProcess.NativeProcess.Name)))
            {
              throw new InvalidOperationException (string.Format ("Package '{0}' is not debuggable.\nPlease ensure you're trying to connect to a 'Debug' application.\nAlternatively, completely uninstall the current app and try again.", Program.DebugProcess.NativeProcess.Name));
            }

            Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Attaching to '{0}'...", Program.DebugProcess.NativeProcess.Name)), null, null);

            LoggingUtils.RequireOk (Program.Attach (m_sdmCallback), "Failed to attach to target application.");

            CLangDebuggeeThread currentThread = null;

            NativeDebugger.RunInterruptOperation (delegate (CLangDebugger debugger)
            {
              debugger.NativeProgram.RefreshAllThreads ();

              currentThread = debugger.NativeProgram.GetThread (debugger.NativeProgram.CurrentThreadId);

              if (currentThread == null)
              {
                // Lack of current thread is usually a good indication that connection/attaching failed.
                throw new InvalidOperationException (string.Format ("Failed to retrieve program's main thread (tid: {0}).", debugger.NativeProgram.CurrentThreadId));
              }
            });

            Broadcast (new DebugEngineEvent.ProgramCreate (), Program, null);

            Broadcast (new DebugEngineEvent.LoadComplete (), Program, currentThread);

            if (dwReason == enum_ATTACH_REASON.ATTACH_REASON_LAUNCH)
            {
              Broadcast (new DebugEngineEvent.EntryPoint (), Program, currentThread);
            }

            Broadcast (new DebugEngineEvent.AttachComplete (), Program, null);

            Broadcast (new DebugEngineEvent.DebuggerLogcatEvent (debuggingDevice), Program, null);

            Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.LogStatus, string.Format ("Attached successfully to '{0}'.", Program.DebugProcess.NativeProcess.Name)), null, null);

            Broadcast (new DebugEngineEvent.DebuggerConnectionEvent (DebugEngineEvent.DebuggerConnectionEvent.EventType.CloseDialog, string.Empty), null, null);
          }
          catch (Exception e)
          {
            LoggingUtils.HandleException (e);

            Broadcast (ad7Callback, new DebugEngineEvent.Error (e.Message, true), Program, null);

            Detach (Program);
          }
        });

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

        Broadcast (ad7Callback, new DebugEngineEvent.Error (e.Message, true), Program, null);

        Detach (Program);

        return Constants.E_FAIL;
      }
    }
예제 #18
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }

            try
            {
                AD_PROCESS_ID processId = EngineUtils.GetProcessId(rgpPrograms[0]);

                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process
                if (_pollThread == null)
                {
                    // We are being asked to debug a process when we currently aren't debugging anything
                    _pollThread = new WorkerThread();

                    _engineCallback = new EngineCallback(this, ad7Callback);

                    _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError;
                }
                else
                {
                    if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id))
                    {
                        Debug.Fail("Asked to attach to a process while we are debugging");
                        return(VSConstants.E_FAIL);
                    }
                }

                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                this.ProgramCreateEventSent = true;

                return(VSConstants.S_OK);
            }
            catch (MIException e)
            {
                return(e.HResult);
            }
            catch (Exception e) when(ExceptionHelper.BeforeCatch(e, reportOnlyCorrupting: true))
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #19
0
        /// <summary>
        /// Attaches a debug engine (DE) to a program or programs. Called by the session debug manager (SDM) when the DE is running in-process to the SDM.
        /// </summary>
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugEngine2.Attach");

            // Save program
            program = rgpPrograms[0] as DebugProgram;
            if (program == null)
            {
                return(VSConstants.E_INVALIDARG);
            }

            // Update program state
            CopyExceptionMapToProgram();

            //eventCallback.Send(process, new ProcessCreateEvent());
            eventCallback.Send(program, new ProgramCreateEvent());
            return(VSConstants.S_OK);
        }
예제 #20
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            //Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
            Debug.Assert(m_ad7ProgramId == Guid.Empty);
            // MessageBox.Show("IDebugEngine2.Attach", "Debugger debugging", MessageBoxButtons.OK, 0);

            if (celtPrograms != 1)
            {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }

            try
            {
                int processId = EngineUtils.GetProcessId(rgpPrograms[0]);
                if (processId == 0)
                {
                    return(EngineConstants.E_NOTIMPL); // sample engine only supports system processes
                }

                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process

                /* if (m_pollThread == null)
                 * {
                 *   // We are being asked to debug a process when we currently aren't debugging anything
                 *   m_pollThread = new WorkerThread();
                 *
                 *   m_engineCallback = new EngineCallback(this, ad7Callback);
                 *
                 *   // Complete the win32 attach on the poll thread
                 *   m_pollThread.RunOperation(new Operation(delegate
                 *   {
                 *       m_debuggedProcess = Worker.AttachToProcess(m_engineCallback, processId);
                 *   }));
                 *
                 *   m_pollThread.SetDebugProcess(m_debuggedProcess);
                 * }
                 * else
                 * {
                 *   if (processId != m_debuggedProcess.Id)
                 *   {
                 *       Debug.Fail("Asked to attach to a process while we are debugging");
                 *       return EngineConstants.E_FAIL;
                 *   }
                 *
                 *   m_pollThread.SetDebugProcess(m_debuggedProcess);
                 * }             */

                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);

                // start polling for debug events on the poll thread

                /*m_pollThread.RunOperationAsync(new Operation(delegate
                 * {
                 *  m_debuggedProcess.ResumeEventPump();
                 * }));*/

                return(EngineConstants.S_OK);
            }
            catch (ComponentException e)
            {
                return(e.HRESULT);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
        }
예제 #21
0
파일: AD7Engine.cs 프로젝트: xiexin36/VSLua
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            int processId = EngineUtils.GetProcessId(rgpPrograms[0]);

            if (processId == 0)
            {
                return(VSConstants.E_NOTIMPL);
            }

            pID = (uint)processId;

            events = ad7Callback;

            EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_ad7ProgramId));

            AD7EngineCreateEvent.Send(this);

            AD7ProgramCreateEvent.Send(this);

            debugThread = new AD7Thread(this);

            AD7ThreadCreateEvent.Send(this);

            // This event is optional
            AD7LoadCompleteEvent.Send(this);


            return(VSConstants.S_OK);
        }
예제 #22
0
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_program != null);

            IDebugProcess2 process;
            IDebugProgram2 program = rgpPrograms[0];

            EngineUtils.RequireOk(program.GetProcess(out process));

            Guid attachedGuid;

            EngineUtils.RequireOk(program.GetProgramId(out attachedGuid));
            _program.AttachDebugger(attachedGuid);

            Debug.WriteLine("IDebugEngine2.Attach: invoking load callbacks");
            // The SDM will invoke ContinueFromSynchronousEvent with AD7LoadCompleteEvent. At that point,
            // breakpoints from design mode will have already been placed, and the program can be launched.
            _callbacks.OnAttach();

            return(VSConstants.S_OK);
        }
예제 #23
0
        /// <summary>
        ///     Attaches to the specified program nodes. This is the main entry point to debugging.
        /// </summary>
        /// <remarks>
        ///     This method is responsible for firing the correct Visual Studio events to begin debugging
        ///     and then to start the actual PowerShell execution.
        /// </remarks>
        /// <param name="rgpPrograms">The programs.</param>
        /// <param name="rgpProgramNodes">The program nodes.</param>
        /// <param name="celtPrograms">The celt programs.</param>
        /// <param name="pCallback">The callback.</param>
        /// <param name="dwReason">The reason.</param>
        /// <returns></returns>
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms,
                          IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            Log.Debug("Attaching the debug engine.");

            Guid id;
            rgpPrograms[0].GetProgramId(out id);

            if (_node == null)
            {
                _node = rgpProgramNodes[0] as ScriptProgramNode;
                _node.IsAttachedProgram = dwReason == enum_ATTACH_REASON.ATTACH_REASON_USER;
            }

            _node.Id = id;

            var publisher = (IDebugProgramPublisher2) new DebugProgramPublisher();
            publisher.PublishProgramNode(_node);

            _events = new EngineEvents(this, pCallback);
            _events.RunspaceRequest();
            _events.EngineCreated();
            _events.ProgramCreated(_node);
            _events.EngineLoaded();

            _events.DebugEntryPoint();

            Task.Factory.StartNew(Execute);

            return VSConstants.S_OK;
        }
예제 #24
0
        public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            if (celtPrograms == 0)
            {
                return(VSConstants.S_OK);
            }

            if (pCallback == null)
            {
                throw new ArgumentNullException("pCallback");
            }
            if (rgpPrograms == null || rgpPrograms.Length < celtPrograms)
            {
                throw new ArgumentException();
            }
            if (rgpProgramNodes == null || rgpProgramNodes.Length < celtPrograms)
            {
                throw new ArgumentException();
            }

            if (celtPrograms > 1)
            {
                throw new NotImplementedException();
            }

            if (dwReason != enum_ATTACH_REASON.ATTACH_REASON_LAUNCH)
            {
                throw new NotImplementedException();
            }

            JavaDebugProgram program = rgpProgramNodes[0] as JavaDebugProgram;

            if (program == null)
            {
                throw new NotSupportedException();
            }

            lock (_programs)
            {
                _programs.Add(program);
            }

            DebugEvent @event = new DebugEngineCreateEvent(enum_EVENTATTRIBUTES.EVENT_ASYNCHRONOUS, this);

            pCallback.Event(this, program.GetProcess(), program, null, @event);

            program.InitializeDebuggerChannel(this, pCallback);
            return(VSConstants.S_OK);
        }
예제 #25
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.WriteLine("PythonEngine Attach Begin " + GetHashCode());

            AssertMainThread();
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("Python debugging only supports one program in a process");
                throw new ArgumentException();
            }

            int processId = EngineUtils.GetProcessId(rgpPrograms[0]);

            if (processId == 0)
            {
                // engine only supports system processes
                Debug.WriteLine("PythonEngine failed to get process id during attach");
                return(VSConstants.E_NOTIMPL);
            }

            EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null)
            {
                // TODO: Where do we get the language version from?
                _events = ad7Callback;

                var attachRes = PythonProcess.TryAttach(processId, out _process);
                if (attachRes != ConnErrorMessages.None)
                {
                    string msg;
                    switch (attachRes)
                    {
                    case ConnErrorMessages.CannotInjectThread: msg = "Cannot create thread in debuggee process"; break;

                    case ConnErrorMessages.CannotOpenProcess: msg = "Cannot open process for debugging"; break;

                    case ConnErrorMessages.InterpreterNotInitialized: msg = "Python interpreter has not been initialized in this process"; break;

                    case ConnErrorMessages.LoadDebuggerBadDebugger: msg = "Failed to load debugging script (incorrect version of script?)"; break;

                    case ConnErrorMessages.LoadDebuggerFailed: msg = "Failed to compile debugging script"; break;

                    case ConnErrorMessages.OutOfMemory: msg = "Out of memory"; break;

                    case ConnErrorMessages.PythonNotFound: msg = "Python interpreter not found"; break;

                    case ConnErrorMessages.TimeOut: msg = "Timeout while attaching"; break;

                    case ConnErrorMessages.UnknownVersion: msg = "Unknown Python version loaded in process"; break;

                    case ConnErrorMessages.SysNotFound: msg = "sys module not found"; break;

                    case ConnErrorMessages.SysSetTraceNotFound: msg = "settrace not found in sys module"; break;

                    case ConnErrorMessages.PyDebugAttachNotFound: msg = "Cannot find PyDebugAttach.dll at " + attachRes; break;

                    default: msg = "Unknown error"; break;
                    }

                    MessageBox.Show("Failed to attach debugger: " + msg);
                    return(VSConstants.E_FAIL);
                }

                AttachEvents(_process);
                _attached = true;
            }
            else
            {
                if (processId != _process.Id)
                {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return(VSConstants.E_FAIL);
                }
                _attached = false;
            }

            AD7EngineCreateEvent.Send(this);

            lock (_syncLock) {
                _programCreated = true;
                AD7ProgramCreateEvent.Send(this);

                if (_processLoadedThread != null)
                {
                    SendLoadComplete(_processLoadedThread);
                }
            }

            Debug.WriteLine("PythonEngine Attach returning S_OK");
            return(VSConstants.S_OK);
        }
예제 #26
0
        public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] programNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            var integration = InitializationCallback();

            ErrorHandler.ThrowOnFailure(programs[0].GetProcess(out var process));
            _program   = programs[0] as Program;
            _callbacks = new EngineCallbacks(this, _program, process, ad7Callback);

            /* Since VS will add breakpoints right after OnAttach callback, we need to invoke Program.AttachDebugger first */
            _program.AttachDebugger(integration, _callbacks);
            _callbacks.OnAttach();

            return(VSConstants.S_OK);
        }
예제 #27
0
파일: AD7Engine.cs 프로젝트: Microsoft/RTVS
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason) {
            ThrowIfDisposed();

            if (rgpPrograms.Length != 1) {
                throw new ArgumentException("Zero or more than one programs", nameof(rgpPrograms));
            }

            _program = rgpPrograms[0] as RDebugPortSupplier.DebugProgram;
            if (_program == null) {
                throw new ArgumentException("rgpPrograms[0] must be an " + nameof(RDebugPortSupplier.DebugProgram), nameof(rgpPrograms));
            }
            Marshal.ThrowExceptionForHR(_program.GetProgramId(out _programId));

            _events = pCallback;
            Session = _program.Session;
            Tracer = TaskExtensions.RunSynchronouslyOnUIThread(ct => Session.TraceExecutionAsync(ct));
            MainThread = new AD7Thread(this);
            IsConnected = true;

            // Enable breakpoint instrumentation.
            TaskExtensions.RunSynchronouslyOnUIThread(ct => Tracer.EnableBreakpointsAsync(true, ct));

            // Send notification after acquiring the session - we need it in case there were any breakpoints pending before
            // the attach, in which case we'll immediately get breakpoint creation requests as soon as we send these, and
            // we will need the session to process them.
            AD7EngineCreateEvent.Send(this);
            AD7ProgramCreateEvent.Send(this);
            Send(new AD7LoadCompleteEvent(), AD7LoadCompleteEvent.IID);

            var sessionProvider = WorkflowProvider.GetOrCreate().RSessions;
            sessionProvider.BrokerChanged += SessionProvider_BrokerChanged;
                
            // Register event handlers after notifying VS that debug engine has loaded. This order is important because
            // we may get a Browse event immediately, and we want to raise a breakpoint notification in response to that
            // to pause the debugger - but it will be ignored unless the engine has reported its creation.
            // Also, AfterRequest must be registered before Browse, so that we never get in a situation where we get
            // Browse but not AfterRequest that follows it because of a race between raising and registration.
            Session.AfterRequest += Session_AfterRequest;
            Session.Disconnected += Session_Disconnected;

            // If we're already at the Browse prompt, registering the handler will result in its immediate invocation.
            // We want to handle that fully before we process any following AfterRequest event to avoid concurrency issues
            // where we pause and never resume, so hold the lock while adding the handler. 
            lock (_browseLock) {
                Tracer.Browse += Tracer_Browse;
            }

            return VSConstants.S_OK;
        }
예제 #28
0
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            Debug.WriteLine("AD7Engine Attach");
            Guid id;

            if ((DebuggerManager.Instance != null) && (DebuggerManager.Instance.Debugger.IsRunning))
            {
                // If already running, abort.
                MessageBox.Show("Cannot start MySql Debugger. A MySql Debug session is already running", "Error");
                return(HRESULT.E_ATTACH_FAILED_ABORT_SILENTLY);
            }

            rgpPrograms[0].GetProgramId(out id);
            if (id == Guid.Empty)
            {
                return(VSConstants.E_NOTIMPL);
            }

            _events = new AD7Events(this, pCallback);

            try
            {
                DebuggerManager.Init(_events, _node, _breakpoint);
            }
            catch (Exception ex)
            {
                MessageBox.Show(_node.ParentWindow, ex.GetBaseException().Message, "Debugger Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(HRESULT.E_ATTACH_FAILED_ABORT_SILENTLY);
            }

            System.Threading.Thread thread = new System.Threading.Thread(() =>
            {
                DebuggerManager debugger        = DebuggerManager.Instance;
                _node.Debugger                  = debugger;
                debugger.SteppingType           = SteppingTypeEnum.StepInto;
                debugger.Breakpoint             = new AD7Breakpoint(_node, _events);
                debugger.OnEndDebugger         += () => { _events.ProgramDestroyed(_node); };
                debugger.Debugger.RestoreAtExit = true;
                debugger.Run();
            });
            thread.SetApartmentState(System.Threading.ApartmentState.STA);
            thread.Start();

            _node.Id = id;
            _events.EngineCreated();
            _events.ProgramCreated(_node);
            _events.EngineLoaded();
            _events.DebugEntryPoint();

            return(VSConstants.S_OK);
        }
예제 #29
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("Node debugging only supports one program in a process");
                throw new ArgumentException();
            }

            IDebugProgram2 program   = rgpPrograms[0];
            int            processId = EngineUtils.GetProcessId(program);

            if (processId == 0)
            {
                // engine only supports system processes
                Debug.WriteLine("NodeEngine failed to get process id during attach");
                return(VSConstants.E_NOTIMPL);
            }

            EngineUtils.RequireOk(program.GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null)
            {
                // TODO: Where do we get the language version from?
                _events = ad7Callback;

                // Check if we're attaching remotely using the node remote debugging transport
                if (!NodeProcess.TryAttach(processId, out _process))
                {
                    MessageBox.Show("Failed to attach debugger:\n", null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return(VSConstants.E_FAIL);
                }

                AttachProcessEvents(_process);
                _attached = true;
            }
            else
            {
                if (processId != _process.Id)
                {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return(VSConstants.E_FAIL);
                }
            }

            AD7EngineCreateEvent.Send(this);

            lock (_syncLock)
            {
                _programCreated = true;

                if (_processLoadedThread != null)
                {
                    SendLoadComplete(_processLoadedThread);
                }
            }

            Debug.WriteLine("NodeEngine Attach returning S_OK");
            return(VSConstants.S_OK);
        }
예제 #30
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            // Attach the debug engine to a program.
            //
            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process.
            // So could we simplify and move code from LaunchSuspended to here and maybe even
            // eliminate the debughost? Although I supposed DebugHost has some other uses as well.

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

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

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

                // Dummy main thread
                // We dont support threads yet, but the debugger expects threads.
                // So we create a dummy object to represente our only "thread".
            //                m_thread = m_process._threads;
            //                m_thread = new AD7Thread(this, m_process);
                AD7LoadCompleteEvent.Send(this, currentThread());

                // If the reason for attaching is ATTACH_REASON_LAUNCH, the DE needs to send the IDebugEntryPointEvent2 event.
                // See http://msdn.microsoft.com/en-us/library/bb145136%28v=vs.100%29.aspx
                if (dwReason == enum_ATTACH_REASON.ATTACH_REASON_LAUNCH)
                {
                    AD7EntryPointEvent ad7Event = new AD7EntryPointEvent();
                    Guid riidEvent = new Guid(AD7EntryPointEvent.IID);
                    uint attributes = (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;
                    int rc = ad7Callback.Event(this, null, m_program, currentThread(), ad7Event, ref riidEvent, attributes);
                    Debug.Assert(rc == VSConstants.S_OK);
                }
            }
            catch (Exception e)
            {
                return EngineUtils.UnexpectedException(e);
            }
            return VSConstants.S_OK;
        }
예제 #31
0
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            ThrowIfDisposed();

            if (rgpPrograms.Length != 1)
            {
                throw new ArgumentException("Zero or more than one programs", nameof(rgpPrograms));
            }

            _program = rgpPrograms[0] as RDebugPortSupplier.DebugProgram;
            if (_program == null)
            {
                throw new ArgumentException("rgpPrograms[0] must be an " + nameof(RDebugPortSupplier.DebugProgram), nameof(rgpPrograms));
            }
            Marshal.ThrowExceptionForHR(_program.GetProgramId(out _programId));

            _events     = pCallback;
            Session     = _program.Session;
            Tracer      = TaskExtensions.RunSynchronouslyOnUIThread(ct => Session.TraceExecutionAsync(ct));
            MainThread  = new AD7Thread(this);
            IsConnected = true;

            // Enable breakpoint instrumentation.
            TaskExtensions.RunSynchronouslyOnUIThread(ct => Tracer.EnableBreakpointsAsync(true, ct));

            // Send notification after acquiring the session - we need it in case there were any breakpoints pending before
            // the attach, in which case we'll immediately get breakpoint creation requests as soon as we send these, and
            // we will need the session to process them.
            AD7EngineCreateEvent.Send(this);
            AD7ProgramCreateEvent.Send(this);
            Send(new AD7LoadCompleteEvent(), AD7LoadCompleteEvent.IID);

            var sessionProvider = WorkflowProvider.GetOrCreate().RSessions;

            sessionProvider.BrokerChanged += SessionProvider_BrokerChanged;

            // Register event handlers after notifying VS that debug engine has loaded. This order is important because
            // we may get a Browse event immediately, and we want to raise a breakpoint notification in response to that
            // to pause the debugger - but it will be ignored unless the engine has reported its creation.
            // Also, AfterRequest must be registered before Browse, so that we never get in a situation where we get
            // Browse but not AfterRequest that follows it because of a race between raising and registration.
            Session.AfterRequest += Session_AfterRequest;
            Session.Disconnected += Session_Disconnected;

            // If we're already at the Browse prompt, registering the handler will result in its immediate invocation.
            // We want to handle that fully before we process any following AfterRequest event to avoid concurrency issues
            // where we pause and never resume, so hold the lock while adding the handler.
            lock (_browseLock) {
                Tracer.Browse += Tracer_Browse;
            }

            return(VSConstants.S_OK);
        }
예제 #32
0
        }         // ctor

        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            throw new NotImplementedException();
        }
예제 #33
0
        // Attach the debug engine to a program. 
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason) {
            DebugWriteCommand("Attach");

            AssertMainThread();
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1) {
                Debug.Fail("Node debugging only supports one program in a process");
                throw new ArgumentException();
            }

            int processId = EngineUtils.GetProcessId(rgpPrograms[0]);
            if (processId == 0) {
                // engine only supports system processes
                LiveLogger.WriteLine("AD7Engine failed to get process id during attach");
                return VSConstants.E_NOTIMPL;
            }

            EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null) {
                _events = ad7Callback;

                var program = (NodeRemoteDebugProgram)rgpPrograms[0];
                var process = program.DebugProcess;
                var uri = process.DebugPort.Uri;

                _process = new NodeDebugger(uri, process.Id);

                // We only need to do fuzzy comparisons when debugging remotely
                if (!uri.IsLoopback) {
                    _process.IsRemote = true;
                    _process.FileNameMapper = new FuzzyLogicFileNameMapper(EnumerateSolutionFiles());
                }

                AttachEvents(_process);
                _attached = true;
            } else {
                if (processId != _process.Id) {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return VSConstants.E_FAIL;
                }
            }

            lock (_syncLock) {
                _sdmAttached = true;
                HandleLoadComplete();
            }

            LiveLogger.WriteLine("AD7Engine Attach returning S_OK");
            return VSConstants.S_OK;
        }
예제 #34
0
 public /*override*/ int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
 {
     NLogService.TraceEnteringMethod();
     EnsureSessionStarted();
     return(_engine.Attach(rgpPrograms, rgpProgramNodes, celtPrograms, pCallback, dwReason));
 }
예제 #35
0
        public /*override*/ int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            DebugHelper.TraceEnteringMethod();

            try
            {
                _session.Run(_startInfo, _startInfo.SessionOptions);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message + " - " + ex.StackTrace);
            }

            return(_engine.Attach(rgpPrograms, rgpProgramNodes, celtPrograms, pCallback, dwReason));
        }
예제 #36
0
파일: AD7Engine.cs 프로젝트: borota/JTVS
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.WriteLine("JEngine Attach Begin " + GetHashCode());

            AssertMainThread();
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1) {
                Debug.Fail("J debugging only supports one program in a process");
                throw new ArgumentException();
            }

            var program = rgpPrograms[0];
            int processId = EngineUtils.GetProcessId(program);
            if (processId == 0) {
                // engine only supports system processes
                Debug.WriteLine("JEngine failed to get process id during attach");
                return VSConstants.E_NOTIMPL;
            }

            EngineUtils.RequireOk(program.GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null) {
                // TODO: Where do we get the language version from?
                _events = ad7Callback;

                // Check if we're attaching remotely using the J remote debugging transport
                var remoteProgram = program as JRemoteDebugProgram;
                ConnErrorMessages attachRes;
                if (remoteProgram != null) {
                    var remotePort = remoteProgram.DebugProcess.DebugPort;
                    attachRes = JRemoteProcess.TryAttach(remotePort.HostName, remotePort.PortNumber, remotePort.Secret, remotePort.UseSsl, SslErrorHandling.PromptUser, out _process);
                } else {
                    attachRes = JProcess.TryAttach(processId, out _process);
                }
                if (attachRes != ConnErrorMessages.None) {
                    MessageBox.Show("Failed to attach debugger:\n" + attachRes.GetErrorMessage(), null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return VSConstants.E_FAIL;
                }

                AttachEvents(_process);
                _attached = true;
            } else {
                if (processId != _process.Id) {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return VSConstants.E_FAIL;
                }
            }

            AD7EngineCreateEvent.Send(this);

            lock (_syncLock) {
                _programCreated = true;

                if (_processLoadedThread != null) {
                    SendLoadComplete(_processLoadedThread);
                }
            }

            Debug.WriteLine("JEngine Attach returning S_OK");
            return VSConstants.S_OK;
        }
예제 #37
0
        public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            var            program = programs[0];
            IDebugProcess2 process;

            program.GetProcess(out process);
            Guid processId;

            process.GetProcessId(out processId);
            if (processId != this.processId.guidProcessId)
            {
                return(VSConstants.S_FALSE);
            }

            EngineUtils.RequireOk(program.GetProgramId(out programId));

            Task.Run(() => {
                waiter.WaitOne();

                // connect to the local Mono Debugger or SSH tunnel.
                var localhost = IPAddress.Parse("127.0.0.1");
                Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("", localhost, MonoDebuggerPort)),
                            new DebuggerSessionOptions {
                    EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false
                });
            });

            MonoEngineCreateEvent.Send(this);
            MonoProgramCreateEvent.Send(this);

            return(VSConstants.S_OK);
        }
예제 #38
0
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            rgpPrograms[0].GetProgramId(out _programId);
            Callback.EngineCreated();
            Callback.ProgramCreated();

            this.ProgramCreateEventSent = true;

            return(Constants.S_OK);
        }
예제 #39
0
 public override int Attach(IDebugProgram2[] rgpPrograms,
                            IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms,
                            IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
 {
     throw new NotImplementedTestDoubleException();
 }
예제 #40
0
 // Token: 0x0600004C RID: 76 RVA: 0x00003104 File Offset: 0x00001304
 public int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
 {
     if (dwReason != enum_ATTACH_REASON.ATTACH_REASON_USER)
     {
         throw new InvalidOperationException();
     }
     if (celtPrograms != 1U)
     {
         throw new InvalidOperationException();
     }
     if (!this.processes.Any((Process process) => rgpPrograms[0] == process))
     {
         throw new InvalidOperationException();
     }
     Utils.Message("ATTACH: {0}", new object[]
     {
         rgpPrograms[0]
     });
     return(0);
 }
예제 #41
0
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            // Attach the debug engine to a program.
            //
            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process.
            // So could we simplify and move code from LaunchSuspended to here and maybe even
            // eliminate the debughost? Although I supposed DebugHost has some other uses as well.

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

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

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

                // Dummy main thread
                // We dont support threads yet, but the debugger expects threads.
                // So we create a dummy object to represente our only "thread".
                mThread = new AD7Thread(this, mProcess);
                AD7LoadCompleteEvent.Send(this, mThread);
            }
            catch (Exception e)
            {
                return(EngineUtils.UnexpectedException(e));
            }
            return(VSConstants.S_OK);
        }
예제 #42
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }

            try
            {
                AD_PROCESS_ID processId = EngineUtils.GetProcessId(rgpPrograms[0]);

                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out _ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process
                if (_pollThread == null)
                {
                    // We are being asked to debug a process when we currently aren't debugging anything
                    _pollThread = new WorkerThread(Logger);

                    _engineCallback = new EngineCallback(this, ad7Callback);

                    // Complete the win32 attach on the poll thread
                    _pollThread.RunOperation(new Operation(delegate
                    {
                        throw new NotImplementedException();
                    }));

                    _pollThread.PostedOperationErrorEvent += _debuggedProcess.OnPostedOperationError;
                }
                else
                {
                    if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id))
                    {
                        Debug.Fail("Asked to attach to a process while we are debugging");
                        return Constants.E_FAIL;
                    }
                }

                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                this.ProgramCreateEventSent = true;

                return Constants.S_OK;
            }
            catch (MIException e)
            {
                return e.HResult;
            }
            catch (Exception e) when (ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: true))
            {
                return EngineUtils.UnexpectedException(e);
            }
        }
예제 #43
0
        public int Attach(IDebugProgram2[] programs, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            var            program = programs[0];
            IDebugProcess2 process;

            program.GetProcess(out process);
            Guid processId;

            process.GetProcessId(out processId);
            if (processId != this.processId.guidProcessId)
            {
                return(VSConstants.S_FALSE);
            }

            EngineUtils.RequireOk(program.GetProgramId(out programId));

            Task.Run(() =>
            {
                waiter.WaitOne();

                var ipAddress = HostUtils.ResolveHostOrIPAddress(settings.Host);
                Session.Run(new SoftDebuggerStartInfo(new SoftDebuggerConnectArgs("", ipAddress, 6438)),
                            new DebuggerSessionOptions {
                    EvaluationOptions = EvaluationOptions.DefaultOptions, ProjectAssembliesOnly = false
                });
            });

            MonoEngineCreateEvent.Send(this);
            MonoProgramCreateEvent.Send(this);

            return(VSConstants.S_OK);
        }
예제 #44
0
        public /*override*/ int Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 pCallback, enum_ATTACH_REASON dwReason)
        {
            NLogService.TraceEnteringMethod(Logger);

            if (rgpPrograms.Length != 1)
            {
                NLogService.Logger.Error("The debug engine can only be attached to one program at the time.");
                return(VisualStudioExtensionConstants.S_FALSE);
            }

            if (_activeProgram != null)
            {
                NLogService.Logger.Error("The debug engine is already attached.");
                return(VisualStudioExtensionConstants.S_FALSE);
            }

            _activeProgram = rgpPrograms[0];
            _eventCallback = pCallback;

            try
            {
                _session.Run(_startInfo, _startInfo.SessionOptions);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message + " - " + ex.StackTrace);
            }

            return(_engine.Attach(rgpPrograms, rgpProgramNodes, celtPrograms, pCallback, dwReason));
        }
예제 #45
0
        /// <summary>
        /// Attach the debug engine to a program. (http://msdn.microsoft.com/en-us/library/bb145136.aspx)
        /// </summary>
        /// <param name="rgpPrograms"> Represent programs to be attached to. These are port programs. </param>
        /// <param name="rgpProgramNodes"> Represent program nodes, one for each program. The program nodes in this array represent 
        /// the same programs as in pProgram. The program nodes are given so that the DE can identify the programs to attach to. </param>
        /// <param name="aCeltPrograms"> Number of programs and/or program nodes in the pProgram and rgpProgramNodes arrays. </param>
        /// <param name="ad7Callback"> The IDebugEventCallback2 object to be used to send debug events to the SDM. </param>
        /// <param name="dwReason">  A value from the ATTACH_REASON enumeration that specifies the reason for attaching these programs. </param>
        /// <returns> If successful, returns S_OK; otherwise, returns an error code. </returns>
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint aCeltPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            if (aCeltPrograms != 1)
            {
                System.Diagnostics.Debug.Fail("VSNDK Debugger only supports one debug target at a time.");
                throw new ArgumentException();
            }

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

                m_program = rgpPrograms[0];

                // It is NULL when the user attached the debugger to a running process (by using Attach to Process UI). When that
                // happens, some objects must be instantiated, as well as GDB must be launched. Those ones are instantiated/launched
                // by LaunchSuspended and ResumeProcess methods when debugging an open project.
                if (this.m_engineCallback == null)
                {
                    VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = true;
                    m_engineCallback = new EngineCallback(this, ad7Callback);

                    AD7ProgramNodeAttach pnt = (AD7ProgramNodeAttach)m_program;
                    m_process = pnt.m_process;
                    AD7Port port = pnt.m_process._portAttach;
                    string publicKeyPath = Environment.GetEnvironmentVariable("AppData") + @"\BlackBerry\bbt_id_rsa.pub";
                    string progName = pnt.m_programName.Substring(pnt.m_programName.LastIndexOf('/') + 1);

                    string exePath = "";
                    string processesPaths = "";
                    System.IO.StreamReader readProcessesPathsFile = null;
                    // Read the file ProcessesPath.txt to try to get the file location of the executable file.
                    try
                    {
                        readProcessesPathsFile = new System.IO.StreamReader(System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Research In Motion\ProcessesPath.txt");
                        processesPaths = readProcessesPathsFile.ReadToEnd();
                        readProcessesPathsFile.Close();
                    }
                    catch (Exception e)
                    {
                        processesPaths = "";
                    }

                    string searchProgName = progName + "_" + port.m_isSimulator;
                    int begin = processesPaths.IndexOf(searchProgName + ":>");

                    if (begin != -1)
                    {
                        begin += searchProgName.Length + 2;
                        int end = processesPaths.IndexOf("\r\n", begin);

                        exePath = processesPaths.Substring(begin, end - begin) + progName;
                    }
                    else
                    {
                        exePath = "CannotAttachToRunningProcess";
                    }

                    exePath = exePath.Replace("\\", "\\\\\\\\");

                    if (GDBParser.LaunchProcess(pnt.m_programID, exePath, port.m_IP, port.m_isSimulator, port.m_toolsPath, publicKeyPath, port.m_password))
                    {
                        if (exePath == "CannotAttachToRunningProcess")
                        {
                            MessageBox.Show(progName + " is attached to the debugger. However, to be able to debug your application, you must build and deploy it from this computer first.", "No executable file with symbols found.", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        }
                        m_eventDispatcher = new EventDispatcher(this);
                        m_module = new AD7Module();
                        m_progNode = new AD7ProgramNode(m_process._processGUID, m_process._processID, exePath, new Guid(AD7Engine.Id));
                        AddThreadsToProgram();
                    }
                    else
                    {
                        GDBParser.exitGDB();
                        VSNDK.Package.ControlDebugEngine.isDebugEngineRunning = false;
                        return VSConstants.E_FAIL;
                    }
                }
                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                AD7ModuleLoadEvent.Send(this, m_module, true);
                AD7LoadCompleteEvent.Send(this, currentThread());

                // If the reason for attaching is ATTACH_REASON_LAUNCH, the DE needs to send the IDebugEntryPointEvent2 event.
                // See http://msdn.microsoft.com/en-us/library/bb145136%28v=vs.100%29.aspx
                if (dwReason == enum_ATTACH_REASON.ATTACH_REASON_LAUNCH)
                {
                    AD7EntryPointEvent ad7Event = new AD7EntryPointEvent();
                    Guid riidEvent = new Guid(AD7EntryPointEvent.IID);
                    uint attributes = (uint)enum_EVENTATTRIBUTES.EVENT_STOPPING | (uint)enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS;
                    int rc = ad7Callback.Event(this, null, m_program, currentThread(), ad7Event, ref riidEvent, attributes);
                    Debug.Assert(rc == VSConstants.S_OK);
                }
            }
            catch (Exception e)
            {
                return EngineUtils.UnexpectedException(e);
            }
            return VSConstants.S_OK;
        }
예제 #46
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("Node debugging only supports one program in a process");
                throw new ArgumentException();
            }

            IDebugProgram2 program = rgpPrograms[0];
            int processId = EngineUtils.GetProcessId(program);
            if (processId == 0)
            {
                // engine only supports system processes
                Debug.WriteLine("NodeEngine failed to get process id during attach");
                return VSConstants.E_NOTIMPL;
            }

            EngineUtils.RequireOk(program.GetProgramId(out _ad7ProgramId));

            // Attach can either be called to attach to a new process, or to complete an attach
            // to a launched process
            if (_process == null)
            {
                // TODO: Where do we get the language version from?
                _events = ad7Callback;

                // Check if we're attaching remotely using the node remote debugging transport
                if (!NodeProcess.TryAttach(processId, out _process))
                {
                    MessageBox.Show("Failed to attach debugger:\n", null, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return VSConstants.E_FAIL;
                }

                AttachProcessEvents(_process);
                _attached = true;
            }
            else
            {
                if (processId != _process.Id)
                {
                    Debug.Fail("Asked to attach to a process while we are debugging");
                    return VSConstants.E_FAIL;
                }
            }

            AD7EngineCreateEvent.Send(this);

            lock (_syncLock)
            {
                _programCreated = true;

                if (_processLoadedThread != null)
                {
                    SendLoadComplete(_processLoadedThread);
                }
            }

            Debug.WriteLine("NodeEngine Attach returning S_OK");
            return VSConstants.S_OK;
        }
예제 #47
0
        // Attach the debug engine to a program.
        public int Attach(IDebugProgram2[] portProgramArray, IDebugProgramNode2[] programNodeArray, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1)
            {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }
            IDebugProgram2 portProgram = portProgramArray[0];

            Exception exception = null;

            try
            {
                IDebugProcess2 process;
                EngineUtils.RequireOk(portProgram.GetProcess(out process));

                AD_PROCESS_ID processId = EngineUtils.GetProcessId(process);

                EngineUtils.RequireOk(portProgram.GetProgramId(out _ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process
                if (_pollThread == null)
                {
                    if (processId.ProcessIdType != (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM)
                    {
                        Debug.Fail("Invalid process to attach to");
                        throw new ArgumentException();
                    }

                    IDebugPort2 port;
                    EngineUtils.RequireOk(process.GetPort(out port));

                    Debug.Assert(_engineCallback == null);
                    Debug.Assert(_debuggedProcess == null);

                    _engineCallback = new EngineCallback(this, ad7Callback);
                    LaunchOptions launchOptions = CreateAttachLaunchOptions(processId.dwProcessId, port);
                    StartDebugging(launchOptions);
                }
                else
                {
                    if (!EngineUtils.ProcIdEquals(processId, _debuggedProcess.Id))
                    {
                        Debug.Fail("Asked to attach to a process while we are debugging");
                        return(Constants.E_FAIL);
                    }
                }

                AD7EngineCreateEvent.Send(this);
                AD7ProgramCreateEvent.Send(this);
                this.ProgramCreateEventSent = true;

                return(Constants.S_OK);
            }
            catch (Exception e) when(ExceptionHelper.BeforeCatch(e, Logger, reportOnlyCorrupting: true))
            {
                exception = e;
            }

            // If we just return the exception as an HRESULT, we will lose our message, so we instead send up an error event, and
            // return that the attach was canceled
            OnStartDebuggingFailed(exception);
            return(AD7_HRESULT.E_ATTACH_USER_CANCELED);
        }
예제 #48
0
        // Attach the debug engine to a program.
        int IDebugEngine2.Attach(IDebugProgram2[] rgpPrograms, IDebugProgramNode2[] rgpProgramNodes, uint celtPrograms, IDebugEventCallback2 ad7Callback, enum_ATTACH_REASON dwReason)
        {
            //Debug.Assert(Worker.MainThreadId == Worker.CurrentThreadId);
            Debug.Assert(m_ad7ProgramId == Guid.Empty);

            if (celtPrograms != 1) {
                Debug.Fail("SampleEngine only expects to see one program in a process");
                throw new ArgumentException();
            }

            try {
                var processId = EngineUtils.GetProcessId(rgpPrograms[0]);
                if (processId == 0) {
                    return Constants.E_NOTIMPL; // sample engine only supports system processes
                }

                EngineUtils.RequireOk(rgpPrograms[0].GetProgramId(out m_ad7ProgramId));

                // Attach can either be called to attach to a new process, or to complete an attach
                // to a launched process
                if (m_pollThread == null) {
                    throw new NotImplementedException();
                    // We are being asked to debug a process when we currently aren't debugging anything
                    //m_pollThread = new WorkerThread();
                    //m_engineCallback = new EngineCallback(this, ad7Callback);
                    //// Complete the win32 attach on the poll thread
                    //m_pollThread.RunOperation(new Operation(delegate
                    //{
                    //    //m_debuggedProcess = Worker.AttachToProcess(m_engineCallback, processId);
                    //}));

                    //m_pollThread.SetDebugProcess(m_debuggedProcess);
                } else {
                    if (processId != m_debuggedProcess.Id) {
                        Debug.Fail("Asked to attach to a process while we are debugging");
                        return Constants.E_FAIL;
                    }

                    m_debuggedProcess.Attach();
                    m_debuggedProcess.WaitForAttach();
                    m_pollThread.SetDebugProcess(m_debuggedProcess);
                }

                Callback.Send(new AD7EngineCreateEvent(this), null, null);
                Callback.Send(new AD7ProgramCreateEvent(), null);

                // start polling for debug events on the poll thread
                //m_pollThread.RunOperationAsync(() => m_debuggedProcess.ResumeEventPump());

                m_debuggedProcess.Threads.Add(new DebuggedThread { Id = 1 });
                m_pollThread.RunOperationAsync(() => Callback.OnThreadStart(m_debuggedProcess.GetThreads()[0]));

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