public int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId,
                                   ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     DebugHelper.TraceEnteringMethod();
     ppProgramNode = null;
     return(VSConstants.S_OK);
 }
 public int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId,
     ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     DebugHelper.TraceEnteringMethod();
     ppProgramNode = null;
     return VSConstants.S_OK;
 }
Example #3
0
        // 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;
        }
        public int RemoveProgramNode(IDebugProgramNode2 pProgramNode)
        {
            programNodes.Remove(pProgramNode);


            return(Microsoft.VisualStudio.VSConstants.S_OK);
        }
Example #5
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;
        }
 // Gets a program node, given a specific process ID.
 int IDebugProgramProvider2.GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId,
                                                   out IDebugProgramNode2 programNode)
 {
     // This method is used for Just-In-Time debugging support, which this program provider does not support
     programNode = null;
     return(VSConstants.E_NOTIMPL);
 }
        private CorDebugProcess GetProcess(IDebugProgramNode2 programNode)
        {
            AD_PROCESS_ID[] pids = new AD_PROCESS_ID[1];

            programNode.GetHostPid(pids);
            return(GetProcess(pids[0]));
        }
        // Obtains information about programs running, filtered in a variety of ways.
        int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] processArray)
        {
            processArray[0] = new PROVIDER_PROCESS_DATA();

            if (EngineUtils.IsFlagSet((uint)Flags, (int)enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES))
            {
                // The debugger is asking the engine to return the program nodes it can debug. The
                // sample engine claims that it can debug all processes, and returns exsactly one
                // program node for each process. A full-featured debugger may wish to examine the
                // target process and determine if it understands how to debug it.

                IDebugProgramNode2 node = (IDebugProgramNode2)(new AD7ProgramNode((int)ProcessId.dwProcessId));

                IntPtr[] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) };

                IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length);
                Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length);

                processArray[0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES;
                processArray[0].ProgramNodes.Members = destinationArray;
                processArray[0].ProgramNodes.dwCount = (uint)programNodes.Length;

                return(EngineConstants.S_OK);
            }

            return(EngineConstants.S_FALSE);
        }
        int Microsoft.VisualStudio.Debugger.Interop.IDebugPortEx2.GetProgram(IDebugProgramNode2 pProgramNode, out IDebugProgram2 ppProgram)
        {
            CorDebugAppDomain appDomain = GetAppDomain(pProgramNode);

            ppProgram = appDomain;

            return(Utility.COM_HResults.S_OK);
        }
Example #10
0
 public int RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     if (programNodes.Remove(pProgramNode))
     {
         return(VSConstants.S_OK);
     }
     return(VSConstants.S_FALSE);
 }
 /// <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;
 }
 /// <summary>
 /// Retrieves the program node for a specific program.
 /// </summary>
 /// <param name="Flags">
 /// A combination of flags from the PROVIDER_FLAGS enumeration. The following flags are typical for this call:
 /// 
 /// Flag                         Description
 /// PFLAG_REMOTE_PORT            Caller is running on remote machine.
 /// PFLAG_DEBUGGEE               Caller is currently being debugged (additional information about marshalling will be returned for each node).
 /// PFLAG_ATTACHED_TO_DEBUGGEE   Caller was attached to but not launched by the debugger.
 /// </param>
 /// <param name="pPort">The port the calling process is running on.</param>
 /// <param name="ProcessId">An AD_PROCESS_ID structure holding the ID of the process that contains the program in question.</param>
 /// <param name="guidEngine">GUID of the debug engine that the program is attached to (if any).</param>
 /// <param name="programId">ID of the program for which to get the program node.</param>
 /// <param name="ppProgramNode">An IDebugProgramNode2 object representing the requested program node.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public virtual int GetProviderProgramNode( enum_PROVIDER_FLAGS Flags,
     IDebugDefaultPort2 pPort,
     AD_PROCESS_ID ProcessId,
     ref Guid guidEngine,
     ulong programId,
     out IDebugProgramNode2 ppProgramNode)
 {
     Logger.Debug( string.Empty );
     ppProgramNode = null;
     return VSConstants.E_NOTIMPL;
 }
Example #13
0
 int IDebugProgramProvider2.GetProviderProgramNode(
     enum_PROVIDER_FLAGS Flags,
     IDebugDefaultPort2 pPort,
     AD_PROCESS_ID ProcessId,
     ref Guid guidEngine,
     ulong programId,
     out IDebugProgramNode2 ppProgramNode)
 {
     ppProgramNode = null;
     return(VSConstants.E_NOTIMPL);
 }
 /// <summary>
 /// Retrieves the program node for a specific program.
 /// </summary>
 /// <param name="Flags">
 /// A combination of flags from the PROVIDER_FLAGS enumeration. The following flags are typical for this call:
 ///
 /// Flag                         Description
 /// PFLAG_REMOTE_PORT            Caller is running on remote machine.
 /// PFLAG_DEBUGGEE               Caller is currently being debugged (additional information about marshalling will be returned for each node).
 /// PFLAG_ATTACHED_TO_DEBUGGEE   Caller was attached to but not launched by the debugger.
 /// </param>
 /// <param name="pPort">The port the calling process is running on.</param>
 /// <param name="ProcessId">An AD_PROCESS_ID structure holding the ID of the process that contains the program in question.</param>
 /// <param name="guidEngine">GUID of the debug engine that the program is attached to (if any).</param>
 /// <param name="programId">ID of the program for which to get the program node.</param>
 /// <param name="ppProgramNode">An IDebugProgramNode2 object representing the requested program node.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public virtual int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags,
                                           IDebugDefaultPort2 pPort,
                                           AD_PROCESS_ID ProcessId,
                                           ref Guid guidEngine,
                                           ulong programId,
                                           out IDebugProgramNode2 ppProgramNode)
 {
     Logger.Debug(string.Empty);
     ppProgramNode = null;
     return(VSConstants.E_NOTIMPL);
 }
        private void SendProgramEvent(IDebugProgramNode2 programNode, enum_EVENTATTRIBUTES attributes, Guid iidEvent)
        {
            CorDebugProcess   process   = GetProcess(programNode);
            CorDebugAppDomain appDomain = GetAppDomain(programNode);

            IDebugEvent2 evt = new DebugEvent((uint)attributes);

            foreach (IDebugPortEvents2 dpe in m_cpDebugPortEvents2.Sinks)
            {
                dpe.Event(this.DebugPortSupplier.CoreServer, this, (IDebugProcess2)process, (IDebugProgram2)appDomain, evt, ref iidEvent);
            }
        }
Example #16
0
        /// <summary>
        /// Unregisters a program that can be debugged from the port it is running on.
        /// </summary>
        int IDebugPortNotify2.RemoveProgramNode(IDebugProgramNode2 pProgramNode)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugPortNotify2.RemoveProgramNode");
            var program = pProgramNode as DebugProgram;

            if (program == null)
            {
                return(VSConstants.E_INVALIDARG);
            }
            SendEvent(null, this, program.Process, program, new ProgramDestroyEvent(0));
            SendEvent(null, this, program.Process, null, new ProcessDestroyEvent());
            return(VSConstants.S_OK);
        }
Example #17
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;
    }
Example #18
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;
        }
        private CorDebugAppDomain GetAppDomain(IDebugProgramNode2 programNode)
        {
            uint appDomainId;

            CorDebugProcess process = GetProcess(programNode);

            IDebugCOMPlusProgramNode2 node = (IDebugCOMPlusProgramNode2)programNode;

            node.GetAppDomainId(out appDomainId);

            CorDebugAppDomain appDomain = process.GetAppDomainFromId(appDomainId);

            return(appDomain);
        }
Example #20
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;
        }
Example #21
0
        /// <summary>
        /// Registers a program that can be debugged with the port it is running on.
        /// </summary>
        int IDebugPortNotify2.AddProgramNode(IDebugProgramNode2 pProgramNode)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugPortNotify2.AddProgramNode");
            IDebugProcess2 proc;
            var            pid = new AD_PROCESS_ID[1];

            ErrorHandler.ThrowOnFailure(pProgramNode.GetHostPid(pid));
            ErrorHandler.ThrowOnFailure(((IDebugPort2)this).GetProcess(pid[0], out proc));

            // Our implementation conflates ProgramNode and Program,
            // perhaps erroneously.
            var program = (IDebugProgram2)pProgramNode;

            SendEvent(null, this, proc, null, new ProcessCreateEvent());
            SendEvent(null, this, proc, program, new ProgramCreateEvent());
            return(VSConstants.S_OK);
        }
Example #22
0
        public int AddProgramNode(IDebugProgramNode2 programNode)
        {
            programNodes.Add(programNode);
            var port = defaultPortFactory.Create(this);
            // TODO: Should this synchronously call IDebugEngine2.Attach() or should it
            // add a job to the job queue?
            var result = debugEngine.Attach(
                new IDebugProgram2[]
            {
                debugProgramFactory.Create(processFactory.Create("Game Process", port))
            },
                new IDebugProgramNode2[] { programNode }, 1, callback,
                enum_ATTACH_REASON.ATTACH_REASON_LAUNCH);

            HResultChecker.Check(result);
            return(VSConstants.S_OK);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugProgramProvider2 Members

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

        public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA [] processArray)
        {
            //
            // Retrieves a list of running programs from a specified process.
            //

            LoggingUtils.PrintFunction();

            try
            {
                processArray [0] = new PROVIDER_PROCESS_DATA();

                if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0)
                {
                    // The debugger is asking the engine to return the program nodes it can debug. The
                    // sample engine claims that it can debug all processes, and returns exactly one
                    // program node for each process. A full-featured debugger may wish to examine the
                    // target process and determine if it understands how to debug it.

                    IDebugProgramNode2 node = (IDebugProgramNode2)(new DebuggeeProgram(null));

                    IntPtr [] programNodes = { Marshal.GetComInterfaceForObject(node, typeof(IDebugProgramNode2)) };

                    IntPtr destinationArray = Marshal.AllocCoTaskMem(IntPtr.Size * programNodes.Length);

                    Marshal.Copy(programNodes, 0, destinationArray, programNodes.Length);

                    processArray [0].Fields = enum_PROVIDER_FIELDS.PFIELD_PROGRAM_NODES;

                    processArray [0].ProgramNodes.Members = destinationArray;

                    processArray [0].ProgramNodes.dwCount = (uint)programNodes.Length;

                    return(Constants.S_OK);
                }

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

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

        public int RemoveProgramNode(IDebugProgramNode2 pProgramNode)
        {
            //
            // Unregisters a program that can be debugged from the port it is running on.
            //

            LoggingUtils.PrintFunction();

            try
            {
                throw new NotImplementedException();
            }
            catch (NotImplementedException e)
            {
                LoggingUtils.HandleException(e);

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

        public int AddProgramNode(IDebugProgramNode2 pProgramNode)
        {
            //
            // Registers a program that can be debugged with the port it is running on.
            //

            LoggingUtils.PrintFunction();

            try
            {
                IDebugProcess2 process;

                DebuggeeProgram program = pProgramNode as DebuggeeProgram;

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

                foreach (IDebugPortEvents2 connectionPoint in m_eventConnectionPoints.Values)
                {
                    ProgramCreate debugEvent = new ProgramCreate();

                    Guid eventGuid = ComUtils.GuidOf(debugEvent);

                    int handle = connectionPoint.Event(null, this, process, program, debugEvent, ref eventGuid);

                    if (handle == unchecked ((int)0x80010108)) // RPC_E_DISCONNECTED
                    {
                        continue;                              // Connection point was previously used.
                    }

                    LoggingUtils.RequireOk(handle);
                }

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

                return(Constants.E_FAIL);
            }
        }
        /// <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;
        }
 // Gets a program node, given a specific process ID.
 int IDebugProgramProvider2.GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId,
                                                   out IDebugProgramNode2 programNode)
 {
     // This method is used for Just-In-Time debugging support, which this program provider does not support
     programNode = null;
     return VSConstants.E_NOTIMPL;
 }
 /// <summary>
 ///     Gets a program node, given a specific process ID.
 /// </summary>
 /// <param name="flags">The flags.</param>
 /// <param name="port">The port.</param>
 /// <param name="processId">The process identifier.</param>
 /// <param name="guidEngine">The unique identifier engine.</param>
 /// <param name="programId">The program identifier.</param>
 /// <param name="programNode">The program node.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public int GetProviderProgramNode(enum_PROVIDER_FLAGS flags, IDebugDefaultPort2 port, AD_PROCESS_ID processId,
                                   ref Guid guidEngine, ulong programId, out IDebugProgramNode2 programNode)
 {
     programNode = null;
     return(S_FALSE);
 }
Example #29
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;
      }
    }
Example #30
0
        int Microsoft.VisualStudio.Debugger.Interop.IDebugPortEx2.GetProgram(IDebugProgramNode2 pProgramNode, out IDebugProgram2 ppProgram)
        {
            CorDebugAppDomain appDomain = GetAppDomain( pProgramNode );
            ppProgram = appDomain;

            return Utility.COM_HResults.S_OK;
        }
Example #31
0
 public int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Retrieves the program node for a specific program.
        /// </summary>
        /// <param name="flags">A combination of flags from the <see cref="PROVIDER_FLAGS"/> enumeration.</param>
        /// <param name="port">The port the calling process is running on.</param>
        /// <param name="processId">An <see cref="AD_PROCESS_ID"/> structure holding the ID of the process that contains the program in question.</param>
        /// <param name="guidEngine">GUID of the debug engine that the program is attached to (if any).</param>
        /// <param name="programId">ID of the program for which to get the program node.</param>
        /// <param name="programNode">An <see cref="IDebugProgramNode2"/> object representing the requested program node.</param>
        /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
        public int GetProviderProgramNode(enum_PROVIDER_FLAGS flags, IDebugDefaultPort2 port, AD_PROCESS_ID processId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 programNode)
        {
            /* The following flags are typical for this call:
             *
             *   PFLAG_REMOTE_PORT:             Caller is running on remote machine.
             *   PFLAG_DEBUGGEE:                Caller is currently being debugged (additional information about marshalling will be returned for each node).
             *   PFLAG_ATTACHED_TO_DEBUGGEE:    Caller was attached to but not launched by the debugger.
             */

            programNode = null;
            return(VSConstants.E_NOTIMPL);
        }
Example #33
0
        private CorDebugAppDomain GetAppDomain( IDebugProgramNode2 programNode )
        {
            uint appDomainId;

            CorDebugProcess process = GetProcess( programNode );

            IDebugCOMPlusProgramNode2 node = (IDebugCOMPlusProgramNode2)programNode;
            node.GetAppDomainId( out appDomainId );

            CorDebugAppDomain appDomain = process.GetAppDomainFromId( appDomainId );

            return appDomain;
        }
 public int GetProgram(IDebugProgramNode2 pProgramNode, out IDebugProgram2 ppProgram)
 {
     throw new NotImplementedException();
 }
Example #35
0
 public int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     ppProgramNode = null;
     return 0;
 }
Example #36
0
 /// <summary>
 /// Unregisters a program that can be debugged from the port it is running on.
 /// </summary>
 int IDebugPortNotify2.RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     DLog.Debug(DContext.VSDebuggerComCall, "IDebugPortNotify2.RemoveProgramNode");
     var program = pProgramNode as DebugProgram;
     if (program == null)
         return VSConstants.E_INVALIDARG;
     SendEvent(null, this, program.Process, program, new ProgramDestroyEvent(0));
     SendEvent(null, this, program.Process, null, new ProcessDestroyEvent());
     return VSConstants.S_OK;
 }
 int Microsoft.VisualStudio.Debugger.Interop.IDebugProgramEx2.GetProgramNode(out IDebugProgramNode2 ppProgramNode)
 {
     ppProgramNode = this;
     return(COM_HResults.S_OK);
 }
Example #38
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;
        }
Example #39
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;
        }
 public int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     Log.Debug("ProgramProvider: GetProviderProgramNode");
     ppProgramNode = null;
     return(VSConstants.S_OK);
 }
 int Microsoft.VisualStudio.Debugger.Interop.IDebugProgramEx2.GetProgramNode(out IDebugProgramNode2 ppProgramNode)
 {
     ppProgramNode = this;
     return Utility.COM_HResults.S_OK;
 }
 public int GetProviderProgramNode(uint Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     ppProgramNode = null;
     return(S_FALSE);
 }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
        {
            //
            // Retrieves the program node for a specific program. Not implemented.
            //

            LoggingUtils.PrintFunction();

            ppProgramNode = null;

            // This method is used for Just-In-Time debugging support, which this program provider does not support
            return(Constants.E_NOTIMPL);
        }
 int Microsoft.VisualStudio.Debugger.Interop.IDebugPortNotify2.RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     SendProgramEvent(pProgramNode, enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS, typeof(IDebugProgramDestroyEvent2).GUID);
     return(Utility.COM_HResults.S_OK);
 }
Example #45
0
 public int RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     throw new NotImplementedException();
 }
Example #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.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;
        }
Example #47
0
        private CorDebugProcess GetProcess( IDebugProgramNode2 programNode )
        {
            AD_PROCESS_ID[] pids = new AD_PROCESS_ID[1];                        

            programNode.GetHostPid( pids );
            return GetProcess( pids[0] );    
        }
Example #48
0
 int IDebugPortNotify2.RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     throw new NotImplementedException();
 }
Example #49
0
        private void SendProgramEvent(IDebugProgramNode2 programNode, enum_EVENTATTRIBUTES attributes, Guid iidEvent)
        {
            CorDebugProcess process = GetProcess( programNode );
            CorDebugAppDomain appDomain = GetAppDomain( programNode );

            IDebugEvent2 evt = new DebugEvent((uint) attributes);
            foreach (IDebugPortEvents2 dpe in m_cpDebugPortEvents2.Sinks)
            {
                dpe.Event(this.DebugPortSupplier.CoreServer, this, (IDebugProcess2)process, (IDebugProgram2) appDomain, evt, ref iidEvent);
            }
        }
Example #50
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;
        }
Example #51
0
 int Microsoft.VisualStudio.Debugger.Interop.IDebugPortNotify2.RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     SendProgramEvent(pProgramNode, enum_EVENTATTRIBUTES.EVENT_SYNCHRONOUS, typeof(IDebugProgramDestroyEvent2).GUID);
     return Utility.COM_HResults.S_OK;
 }
 int IDebugProgramProvider2.GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
   throw new NotImplementedException();
 }
Example #53
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;
        }
Example #54
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;
        }
Example #55
0
 // Token: 0x06000149 RID: 329 RVA: 0x00005A0F File Offset: 0x00003C0F
 public int RemoveProgramNode(IDebugProgramNode2 node)
 {
     this.nodes.Remove(node);
     return(0);
 }
Example #56
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;
        }
Example #57
0
 public int GetProgramNode(out IDebugProgramNode2 ppProgramNode)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Unregisters a program that can be debugged from the port it is running on.
 /// </summary>
 /// <param name="pProgramNode">An IDebugProgramNode2 object that represents the program to be unregistered.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public virtual int RemoveProgramNode(IDebugProgramNode2 pProgramNode)
 {
     Logger.Debug(string.Empty);
     return(VSConstants.E_NOTIMPL);
 }
Example #59
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);
            }
        }
Example #60
0
        /// <summary>
        /// Registers a program that can be debugged with the port it is running on.
        /// </summary>
        int IDebugPortNotify2.AddProgramNode(IDebugProgramNode2 pProgramNode)
        {
            DLog.Debug(DContext.VSDebuggerComCall, "IDebugPortNotify2.AddProgramNode");
            IDebugProcess2 proc;
            var pid = new AD_PROCESS_ID[1];
            ErrorHandler.ThrowOnFailure(pProgramNode.GetHostPid(pid));
            ErrorHandler.ThrowOnFailure(((IDebugPort2)this).GetProcess(pid[0], out proc));

            // Our implementation conflates ProgramNode and Program,
            // perhaps erroneously.
            var program = (IDebugProgram2)pProgramNode;

            SendEvent(null, this, proc, null, new ProcessCreateEvent());
            SendEvent(null, this, proc, program, new ProgramCreateEvent());
            return VSConstants.S_OK;
        }