示例#1
0
 public int GetHostPid(AD_PROCESS_ID[] pHostProcessId)
 {
     DebugHelper.TraceEnteringMethod();
     pHostProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
     pHostProcessId[0].guidProcessId = _processId;
     return VSConstants.S_OK;
 }
示例#2
0
    // Gets the system process identifier for the process hosting a program.
    int IDebugProgramNode2.GetHostPid(AD_PROCESS_ID[] pHostProcessId) {
      // Return the process id of the debugged process
      pHostProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
      pHostProcessId[0].guidProcessId = mProcessID;

      return VSConstants.S_OK;
    }
        public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess)
        {
            Log.Debug("ProgramProvider: GetProviderProcessData");

            if (Flags.HasFlag(enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES))
            {
                var process = Process.GetProcessById((int) ProcessId.dwProcessId);
                foreach (ProcessModule module in process.Modules)
                {
                    if (module.ModuleName.StartsWith("System.Management.Automation", StringComparison.OrdinalIgnoreCase))
                    {
                        var node = new ScriptProgramNode(new ScriptDebugProcess(pPort, ProcessId.dwProcessId));

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

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

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

                        return VSConstants.S_OK;
                    }
                }
            }

            return VSConstants.S_FALSE;
        }
示例#4
0
        // Gets the system process identifier for the process hosting a program.
        int IDebugProgramNode2.GetHostPid(AD_PROCESS_ID[] pHostProcessId) {
            // Return the process id of the debugged process
            pHostProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
            pHostProcessId[0].dwProcessId = (uint)m_processId;

            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;
 }
        public int GetProcess(AD_PROCESS_ID ProcessId, out IDebugProcess2 ppProcess) {
            ppProcess = null;

            if (ProcessId.ProcessIdType != (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM) {
                return VSConstants.E_FAIL;
            }

            IEnumDebugProcesses2 processEnum;
            int hr = EnumProcesses(out processEnum);
            if (ErrorHandler.Failed(hr)) {
                return hr;
            }

            var processes = new IDebugProcess2[1];
            var pids = new AD_PROCESS_ID[1];
            uint fetched = 0;
            while (true) {
                hr = processEnum.Next(1, processes, ref fetched);
                if (ErrorHandler.Failed(hr)) {
                    return hr;
                } else if (fetched == 0) {
                    return VSConstants.E_FAIL;
                }

                if (ErrorHandler.Succeeded(processes[0].GetPhysicalProcessId(pids)) && ProcessId.dwProcessId == pids[0].dwProcessId) {
                    ppProcess = processes[0];
                    return VSConstants.S_OK;
                }
            }
        }
示例#7
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 (Flags.HasFlag(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.

        var node = (IDebugProgramNode2)(new AD7ProgramNode(ProcessId.guidProcessId));

        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 VSConstants.S_OK;
      }

      return VSConstants.S_FALSE;
    }
示例#8
0
        // Gets the system process identifier for the process hosting a program.
        int IDebugProgramNode2.GetHostPid(AD_PROCESS_ID[] pHostProcessId)
        {
            // Return the process id of the debugged process
            pHostProcessId[0] = _processId;

            return Constants.S_OK;
        }
        public static AD_PROCESS_ID GetPhysicalProcessId(this IDebugProcess2 process)
        {
            Contract.Requires<ArgumentNullException>(process != null, "process");

            AD_PROCESS_ID[] processId = new AD_PROCESS_ID[1];
            ErrorHandler.ThrowOnFailure(process.GetPhysicalProcessId(processId));
            return processId[0];
        }
        /// <summary>
        /// Gets the system process identifier for the process hosting the program.
        /// </summary>
        /// <param name="pHostProcessId">Returns the system process identifier for the hosting process.</param>
        /// <returns>
        /// If successful, returns S_OK; otherwise, returns an error code.
        /// </returns>
        public override int GetHostPid( AD_PROCESS_ID[] pHostProcessId )
        {
            Logger.Debug( string.Empty );
            pHostProcessId[0].ProcessIdType = (uint) enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            pHostProcessId[0].guidProcessId = Process.Id;

            return VSConstants.S_OK;
        }
示例#11
0
        public static IDebugProcess2 GetProcess(this IDebugPort2 port, AD_PROCESS_ID processId)
        {
            Contract.Requires<ArgumentNullException>(port != null, "port");

            IDebugProcess2 process;
            ErrorHandler.ThrowOnFailure(port.GetProcess(processId, out process));
            return process;
        }
示例#12
0
        // Gets the system process identifier for the process hosting a program.
        int IDebugProgramNode2.GetHostPid(AD_PROCESS_ID[] pHostProcessId)
        {
            Log.Debug("ScriptProgramNode: Entering GetHostPid");
            // Return the process id of the debugged process
            pHostProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            pHostProcessId[0].guidProcessId = Process.Id;

            return VSConstants.S_OK;
        }
 /// <summary>
 /// Retrieves a list of running programs from a specified process.
 /// </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.
 /// PFLAG_GET_PROGRAM_NODES      Caller is asking for a list of program nodes to be returned.
 /// </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="EngineFilter">An array of GUIDs for debug engines assigned to debug this process (these will be used to filter the programs that are actually returned based on what the supplied engines support; if no engines are specified, then all programs will be returned).</param>
 /// <param name="pProcess">A PROVIDER_PROCESS_DATA structure that is filled in with the requested information.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 /// <remarks>This method is normally called by a process to obtain a list of programs running in that process. The returned information is a list of IDebugProgramNode2 objects.</remarks>
 public virtual int GetProviderProcessData( enum_PROVIDER_FLAGS Flags,
     IDebugDefaultPort2 pPort,
     AD_PROCESS_ID ProcessId,
     CONST_GUID_ARRAY EngineFilter,
     PROVIDER_PROCESS_DATA[] pProcess)
 {
     Logger.Debug( string.Empty );
     return VSConstants.E_NOTIMPL;
 }
示例#14
0
 public static int GetProcessId(this IDebugProcess2 process)
 {
     if (process == null)
         return 0;
     var id = new AD_PROCESS_ID[1];
     if (process.GetPhysicalProcessId(id) != VSConstants.S_OK)
         return 0;
     return (int)id[0].dwProcessId;
 }
示例#15
0
        public static int GetProcessId(IDebugProcess2 process) {
            AD_PROCESS_ID[] pid = new AD_PROCESS_ID[1];
            EngineUtils.RequireOk(process.GetPhysicalProcessId(pid));

            if (pid[0].ProcessIdType != (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM) {
                return 0;
            }

            return (int)pid[0].dwProcessId;
        }
            public int GetProcess(AD_PROCESS_ID ProcessId, out IDebugProcess2 ppProcess) {
                ppProcess = null;

                if (ProcessId.ProcessIdType != (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM) {
                    return VSConstants.E_FAIL;
                }

                ppProcess = GetProcesses().FirstOrDefault(p => p.ProcessId == ProcessId.dwProcessId);
                return ppProcess != null ? VSConstants.S_OK : VSConstants.E_FAIL;
            }
 /// <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;
 }
示例#18
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();

            // we handle creation of the remote program provider ourselves.  This is because we always load our program provider locally which keeps
            // attach working when developing Python Tools and running/debugging from within VS and in the experimental hive.  When we are installed
            // we install into the GAC so these types are available to create and then remote debugging works as well.  When we're running in the
            // experimental hive we are not in the GAC so if we're created outside of VS (e.g. in msvsmon on the local machine) then we can't get
            // at our program provider and debug->attach doesn't work.
            if (port != null && port.QueryIsLocal() == VSConstants.S_FALSE) {
                IDebugCoreServer3 server;
                if (ErrorHandler.Succeeded(port.GetServer(out server))) {
                    IDebugCoreServer90 dbgServer = server as IDebugCoreServer90;
                    if (dbgServer != null) {
                        Guid g = typeof(IDebugProgramProvider2).GUID;
                        IntPtr remoteProviderPunk;

                        int hr = dbgServer.CreateManagedInstanceInServer(typeof(AD7ProgramProvider).FullName, typeof(AD7ProgramProvider).Assembly.FullName, 0, ref g, out remoteProviderPunk);
                        try {
                            if (ErrorHandler.Succeeded(hr)) {
                                var remoteProvider = (IDebugProgramProvider2)Marshal.GetObjectForIUnknown(remoteProviderPunk);
                                return remoteProvider.GetProviderProcessData(Flags, null, ProcessId, EngineFilter, processArray);
                            }
                        } finally {
                            if (remoteProviderPunk != IntPtr.Zero) {
                                Marshal.Release(remoteProviderPunk);
                            }
                        }
                    }
                }
            } else if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0 ) {
                // The debugger is asking the engine to return the program nodes it can debug. We check
                // each process if it has a python##.dll or python##_d.dll loaded and if it does
                // then we report the program as being a Python process.

                if (DebugAttach.IsPythonProcess((int)ProcessId.dwProcessId)) {
                    IDebugProgramNode2 node = 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 VSConstants.S_OK;
                }
            }

            return VSConstants.S_FALSE;
        }
        public DebuggedProcess(AD7Engine engine, IPAddress ipAddress, EngineCallback callback)
        {
            _engine = engine;
            _ipAddress = ipAddress;
            Instance = this;

            // we do NOT have real Win32 process IDs, so we use a guid
            AD_PROCESS_ID pid = new AD_PROCESS_ID();
            pid.ProcessIdType = (int)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            pid.guidProcessId = Guid.NewGuid();
            this.Id = pid;

            _callback = callback;
        }
示例#20
0
    // Establishes a callback to watch for provider events associated with specific kinds of processes
    int IDebugProgramProvider2.WatchForProviderEvents(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, ref Guid guidLaunchingEngine, IDebugPortNotify2 ad7EventCallback) {
      // The sample debug engine is a native debugger, and can therefore always provide a program node
      // in GetProviderProcessData. Non-native debuggers may wish to implement this method as a way
      // of monitoring the process before code for their runtime starts. For example, if implementing a 
      // 'foo script' debug engine, one could attach to a process which might eventually run 'foo script'
      // before this 'foo script' started.
      //
      // To implement this method, an engine would monitor the target process and call AddProgramNode
      // when the target process started running code which was debuggable by the engine. The 
      // enum_PROVIDER_FLAGS.PFLAG_ATTACHED_TO_DEBUGGEE flag indicates if the request is to start
      // or stop watching the process.

      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;
      }
    }
示例#22
0
 // 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);
 }
示例#23
0
 public AD7ProgramNode(AD_PROCESS_ID processId, Guid engineGuid)
 {
     _processId  = processId;
     _engineGuid = engineGuid;
 }
示例#24
0
 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);
 }
示例#25
0
 public int WatchForProviderEvents(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId,
                                   CONST_GUID_ARRAY EngineFilter, ref Guid guidLaunchingEngine, IDebugPortNotify2 pEventCallback)
 {
     DebugHelper.TraceEnteringMethod();
     return(VSConstants.S_OK);
 }
示例#26
0
        public int LaunchSuspended(string server, IDebugPort2 port, string exe, string args, string directory, string environment, string options, enum_LAUNCH_FLAGS launchFlags, uint standardInput, uint standardOutput, uint standardError, IDebugEventCallback2 callback, out IDebugProcess2 process)
        {
            waiter   = new AutoResetEvent(false);
            settings = MonoDebuggerSettings.Parse(options);

            Task.Run(() =>
            {
                var outputWindow    = (IVsOutputWindow)Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsOutputWindow));
                var generalPaneGuid = VSConstants.GUID_OutWindowDebugPane;
                outputWindow.GetPane(ref generalPaneGuid, out this.outputWindow);

                // Upload the contents of the output folder to the target directory
                if (connection == null)
                {
                    connection = ConnectionManager.Get(settings);
                    if (!connection.IsConnected)
                    {
                        Log("Connecting SSH and SFTP...");
                        connection.Connect();
                        Log("Connected");
                    }
                }

                Log("Uploading program...");

                // Ensure target directory exists:
                var targetDirectories = directory.Split('/');
                foreach (var part in targetDirectories)
                {
                    if (!connection.Sftp.Exists(part))
                    {
                        connection.Sftp.CreateDirectory(part);
                    }
                    connection.Sftp.ChangeDirectory(part);
                }
                foreach (var _ in targetDirectories)
                {
                    connection.Sftp.ChangeDirectory("..");
                }

                var outputDirectory = new DirectoryInfo(Path.GetDirectoryName(exe));
                foreach (var file in outputDirectory.EnumerateFiles().Where(x => x.Extension == ".dll" || x.Extension == ".mdb" || x.Extension == ".exe"))
                {
                    using (var stream = file.OpenRead())
                    {
                        connection.Sftp.UploadFile(stream, $"{directory}/{file.Name}", true);
                    }
                    Log($"Uploaded {file.FullName}");
                }
                Log("Done");

                var targetExe = directory + "/" + Path.GetFileName(exe);
                connection.Ssh.RunCommand("cd ~");
                Log("Launching application");
                var commandText = $"mono --debug=mdb-optimizations --debugger-agent=transport=dt_socket,address=0.0.0.0:6438,server=y {targetExe}";
                connection.Ssh.RunCommand("kill $(ps auxww | grep '" + commandText + "' | awk '{print $2}')", this.outputWindow, null);
                runCommand = connection.Ssh.BeginCommand(commandText, this.outputWindow, out runCommandAsyncResult);

                // Trigger that the app is now running for whomever might be waiting for that signal
                waiter.Set();
            });

            Session              = new SoftDebuggerSession();
            Session.TargetReady += (sender, eventArgs) =>
            {
                var activeThread = Session.ActiveThread;
                ThreadManager.Add(activeThread, new MonoThread(this, activeThread));
//                Session.Stop();
            };
            Session.ExceptionHandler = exception => true;
            Session.TargetExited    += (sender, x) =>
            {
//                runCommand.EndExecute(runCommandAsyncResult);
                Send(new MonoProgramDestroyEvent((uint?)x.ExitCode ?? 0), MonoProgramDestroyEvent.IID, null);
            };
            Session.TargetUnhandledException += (sender, x) =>
            {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0))
                {
                    IsUnhandled = true
                }, MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.LogWriter            = (stderr, text) => Console.WriteLine(text);
            Session.OutputWriter         = (stderr, text) => Console.WriteLine(text);
            Session.TargetThreadStarted += (sender, x) => ThreadManager.Add(x.Thread, new MonoThread(this, x.Thread));
            Session.TargetThreadStopped += (sender, x) =>
            {
                ThreadManager.Remove(x.Thread);
            };
            Session.TargetStopped         += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetStarted         += (sender, x) => Console.WriteLine();
            Session.TargetSignaled        += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetInterrupted     += (sender, x) => Console.WriteLine(x.Type);
            Session.TargetExceptionThrown += (sender, x) =>
            {
                Send(new MonoExceptionEvent(x.Backtrace.GetFrame(0)), MonoExceptionEvent.IID, ThreadManager[x.Thread]);
            };
            Session.TargetHitBreakpoint += (sender, x) =>
            {
                var breakpoint        = x.BreakEvent as Breakpoint;
                var pendingBreakpoint = breakpointManager[breakpoint];
                Send(new MonoBreakpointEvent(new MonoBoundBreakpointsEnum(pendingBreakpoint.BoundBreakpoints)), MonoBreakpointEvent.IID, ThreadManager[x.Thread]);
            };

            processId = new AD_PROCESS_ID();
            processId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            processId.guidProcessId = Guid.NewGuid();

            EngineUtils.CheckOk(port.GetProcess(processId, out process));
            Callback = callback;

            return(VSConstants.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 GetPhysicalProcessId(AD_PROCESS_ID[] pProcessId)
 {
   pProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
   pProcessId[0].guidProcessId = Id;
   return VSConstants.S_OK;
 }
 /// <summary>
 ///     Establishes a callback to watch for provider events associated with specific kinds of processes.
 /// </summary>
 /// <param name="flags">The flags.</param>
 /// <param name="port">The port.</param>
 /// <param name="processId">The process identifier.</param>
 /// <param name="engineFilter">The engine filter.</param>
 /// <param name="guidLaunchingEngine">The unique identifier launching engine.</param>
 /// <param name="eventCallback">The event callback.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public int WatchForProviderEvents(enum_PROVIDER_FLAGS flags, IDebugDefaultPort2 port, AD_PROCESS_ID processId,
                                   CONST_GUID_ARRAY engineFilter, ref Guid guidLaunchingEngine, IDebugPortNotify2 eventCallback)
 {
     return(S_OK);
 }
示例#30
0
        private CorDebugProcess GetProcess( IDebugProgramNode2 programNode )
        {
            AD_PROCESS_ID[] pids = new AD_PROCESS_ID[1];                        

            programNode.GetHostPid( pids );
            return GetProcess( pids[0] );    
        }
示例#31
0
        // Launches a process by means of the debug engine.
        // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger
        // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program
        // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language),
        // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method
        // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state.
        int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process)
        {
            process = null;
            if (_mixedMode) {
                return VSConstants.E_NOTIMPL;
            }

            Debug.WriteLine("--------------------------------------------------------------------------------");
            Debug.WriteLine("PythonEngine LaunchSuspended Begin " + launchFlags + " " + GetHashCode());
            AssertMainThread();
            Debug.Assert(_events == null);
            Debug.Assert(_process == null);
            Debug.Assert(_ad7ProgramId == Guid.Empty);

            _events = ad7Callback;
            _engineCreated = _programCreated = false;
            _loadComplete.Reset();

            if (options != null) {
                ParseOptions(options);
            }

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

            // If this is a windowed application, there's no console to wait on, so disable those flags if they were set.
            if (_debugOptions.HasFlag(PythonDebugOptions.IsWindowsApplication)) {
                _debugOptions &= ~(PythonDebugOptions.WaitOnNormalExit | PythonDebugOptions.WaitOnAbnormalExit);
            }

            Guid processId;
            if (_debugOptions.HasFlag(PythonDebugOptions.AttachRunning)) {
                if (!Guid.TryParse(exe, out processId)) {
                    Debug.Fail("When PythonDebugOptions.AttachRunning is used, the 'exe' parameter must be a debug session GUID.");
                    return VSConstants.E_INVALIDARG;
                }

                _process = DebugConnectionListener.GetProcess(processId);
                _attached = true;
                _pseudoAttach = true;
            } else {
                _process = new PythonProcess(_languageVersion, exe, args, dir, env, _interpreterOptions, _debugOptions, _dirMapping);
            }

            if (!_debugOptions.HasFlag(PythonDebugOptions.AttachRunning)) {
                _process.Start(false);
            }

            AttachEvents(_process);

            AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();
            adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
            adProcessId.dwProcessId = (uint)_process.Id;

            EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));
            Debug.WriteLine("PythonEngine LaunchSuspended returning S_OK");
            Debug.Assert(process != null);
            Debug.Assert(!_process.HasExited);

            return VSConstants.S_OK;
        }
示例#32
0
 int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess)
 {
     return(VSConstants.S_FALSE);
 }
示例#33
0
        // Launches a process by means of the debug engine.
        // Normally, Visual Studio launches a program using the IDebugPortEx2::LaunchSuspended method and then attaches the debugger
        // to the suspended program. However, there are circumstances in which the debug engine may need to launch a program
        // (for example, if the debug engine is part of an interpreter and the program being debugged is an interpreted language),
        // in which case Visual Studio uses the IDebugEngineLaunch2::LaunchSuspended method
        // The IDebugEngineLaunch2::ResumeProcess method is called to start the process after the process has been successfully launched in a suspended state.
        int IDebugEngineLaunch2.LaunchSuspended(string pszServer, IDebugPort2 port, string exe, string args, string dir, string env, string options, enum_LAUNCH_FLAGS launchFlags, uint hStdInput, uint hStdOutput, uint hStdError, IDebugEventCallback2 ad7Callback, out IDebugProcess2 process)
        {
            Debug.Assert(m_ad7ProgramId == Guid.Empty);

            m_ad7ProgramId = Guid.NewGuid();

            STARTUPINFO si = new STARTUPINFO();

            pi = new PROCESS_INFORMATION();

            // try/finally free
            bool procOK = NativeMethods.CreateProcess(exe,
                                                      args,
                                                      IntPtr.Zero,
                                                      IntPtr.Zero,
                                                      false,
                                                      ProcessCreationFlags.CREATE_SUSPENDED,
                                                      IntPtr.Zero,
                                                      null,
                                                      ref si,
                                                      out pi);

            pID = pi.dwProcessId;
            Task writepipeOK = WriteNamedPipeAsync();
            Task readpipeOK  = ReadNamedPipeAsync();

            threadHandle = pi.hThread;
            IntPtr processHandle = pi.hProcess;

            // Inject LuaDebug into host
            IntPtr loadLibAddr = DLLInjector.GetProcAddress(DLLInjector.GetModuleHandle("kernel32.dll"), "LoadLibraryA");

            string VS140ExtensionPath = Path.Combine(Path.GetDirectoryName(typeof(EngineConstants).Assembly.Location), "LuaDetour");
            string luaDetoursDllName  = Path.Combine(VS140ExtensionPath, "LuaDetours.dll");

            if (!File.Exists(luaDetoursDllName))
            {
                process = null;
                return(VSConstants.E_FAIL);
            }
            IntPtr allocMemAddress1 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero,
                                                                 (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))),
                                                                 DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE);

            UIntPtr bytesWritten1;

            DLLInjector.WriteProcessMemory(processHandle, allocMemAddress1,
                                           Encoding.Default.GetBytes(luaDetoursDllName),
                                           (uint)((luaDetoursDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten1);
            IntPtr hRemoteThread1 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress1, 0, IntPtr.Zero);

            IntPtr[] handles1 = new IntPtr[] { hRemoteThread1 };
            uint     index1;

            NativeMethods.CoWaitForMultipleHandles(0, -1, handles1.Length, handles1, out index1);

            string debugDllName = Path.Combine(VS140ExtensionPath, "LuaDebug32.dll");

            IntPtr allocMemAddress2 = DLLInjector.VirtualAllocEx(processHandle, IntPtr.Zero,
                                                                 (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))),
                                                                 DLLInjector.MEM_COMMIT | DLLInjector.MEM_RESERVE, DLLInjector.PAGE_READWRITE);

            UIntPtr bytesWritten2;

            DLLInjector.WriteProcessMemory(processHandle, allocMemAddress2,
                                           Encoding.Default.GetBytes(debugDllName), (uint)((debugDllName.Length + 1) * Marshal.SizeOf(typeof(char))), out bytesWritten2);

            IntPtr hRemoteThread2 = DLLInjector.CreateRemoteThread(processHandle, IntPtr.Zero, 0, loadLibAddr, allocMemAddress2, 0, IntPtr.Zero);

            IntPtr[] handles = new IntPtr[] { hRemoteThread2 };
            uint     index2;

            NativeMethods.CoWaitForMultipleHandles(0, -1, handles.Length, handles, out index2);


            AD_PROCESS_ID adProcessId = new AD_PROCESS_ID();

            adProcessId.ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_SYSTEM;
            adProcessId.dwProcessId   = pi.dwProcessId;

            EngineUtils.RequireOk(port.GetProcess(adProcessId, out process));
            debugProcess = process;

            return(VSConstants.S_OK);
        }
示例#34
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 loose 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);
        }
 /// <summary>
 ///     Obtains information about programs running, filtered in a variety of ways.
 /// </summary>
 /// <param name="flags">The flags.</param>
 /// <param name="port">The port.</param>
 /// <param name="processId">The process identifier.</param>
 /// <param name="engineFilter">The engine filter.</param>
 /// <param name="process">The process.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public int GetProviderProcessData(enum_PROVIDER_FLAGS flags, IDebugDefaultPort2 port, AD_PROCESS_ID processId,
                                   CONST_GUID_ARRAY engineFilter, PROVIDER_PROCESS_DATA[] process)
 {
     return(S_FALSE);
 }
示例#36
0
 public int GetHostPid(AD_PROCESS_ID[] pHostProcessId)
 {
     return _process.GetPhysicalProcessId(pHostProcessId);
 }
 /// <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);
 }
示例#38
0
 public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId,
                                   CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess)
 {
     DebugHelper.TraceEnteringMethod();
     return(VSConstants.S_OK);
 }
示例#39
0
 public static AD_PROCESS_ID GetProcessId(IDebugProcess2 process)
 {
     AD_PROCESS_ID[] pid = new AD_PROCESS_ID[1];
     EngineUtils.RequireOk(process.GetPhysicalProcessId(pid));
     return(pid[0]);
 }
示例#40
0
        public DebuggedProcess(bool bLaunched, LaunchOptions launchOptions, ISampleEngineCallback callback, WorkerThread worker, BreakpointManager bpman, AD7Engine engine, string registryRoot)
        {
            uint processExitCode = 0;

            g_Process          = this;
            _pendingMessages   = new StringBuilder(400);
            _worker            = worker;
            _launchOptions     = launchOptions;
            _breakpointManager = bpman;
            Engine             = engine;
            _libraryLoaded     = new List <string>();
            _loadOrder         = 0;
            MICommandFactory   = MICommandFactory.GetInstance(launchOptions.DebuggerMIMode, this);
            _waitDialog        = MICommandFactory.SupportsStopOnDynamicLibLoad() ? new WaitDialog(ResourceStrings.LoadingSymbolMessage, ResourceStrings.LoadingSymbolCaption) : null;
            Natvis             = new Natvis.Natvis(this);

            // we do NOT have real Win32 process IDs, so we use a guid
            AD_PROCESS_ID pid = new AD_PROCESS_ID();

            pid.ProcessIdType = (int)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            pid.guidProcessId = Guid.NewGuid();
            this.Id           = pid;

            SourceLineCache = new SourceLineCache(this);

            _callback        = callback;
            _moduleList      = new List <DebuggedModule>();
            ThreadCache      = new ThreadCache(callback, this);
            Disassembly      = new Disassembly(this);
            ExceptionManager = new ExceptionManager(MICommandFactory, _worker, _callback, registryRoot);

            VariablesToDelete = new List <string>();

            OutputStringEvent += delegate(object o, string message)
            {
                // We can get messages before we have started the process
                // but we can't send them on until it is
                if (_connected)
                {
                    _callback.OnOutputString(message);
                }
                else
                {
                    _pendingMessages.Append(message);
                }
            };

            LibraryLoadEvent += delegate(object o, EventArgs args)
            {
                ResultEventArgs results = args as MICore.Debugger.ResultEventArgs;
                string          file    = results.Results.TryFindString("host-name");
                if (!string.IsNullOrEmpty(file) && MICommandFactory.SupportsStopOnDynamicLibLoad())
                {
                    _libraryLoaded.Add(file);
                    if (_waitDialog != null)
                    {
                        _waitDialog.ShowWaitDialog(file);
                    }
                }
                else if (this.MICommandFactory.Mode == MIMode.Clrdbg)
                {
                    string id            = results.Results.FindString("id");
                    ulong  baseAddr      = results.Results.FindAddr("base-address");
                    uint   size          = results.Results.FindUint("size");
                    bool   symbolsLoaded = results.Results.FindInt("symbols-loaded") != 0;
                    var    module        = new DebuggedModule(id, file, baseAddr, size, symbolsLoaded, string.Empty, _loadOrder++);
                    lock (_moduleList)
                    {
                        _moduleList.Add(module);
                    }
                    _callback.OnModuleLoad(module);
                }
                else if (!string.IsNullOrEmpty(file))
                {
                    string addr = results.Results.TryFindString("loaded_addr");
                    if (string.IsNullOrEmpty(addr) || addr == "-")
                    {
                        return; // identifies the exe, not a real load
                    }
                    // generate module
                    string id         = results.Results.TryFindString("name");
                    bool   symsLoaded = true;
                    string symPath    = null;
                    if (results.Results.Contains("symbols-path"))
                    {
                        symPath = results.Results.FindString("symbols-path");
                        if (string.IsNullOrEmpty(symPath))
                        {
                            symsLoaded = false;
                        }
                    }
                    else
                    {
                        symPath = file;
                    }
                    ulong loadAddr = results.Results.FindAddr("loaded_addr");
                    uint  size     = results.Results.FindUint("size");
                    if (String.IsNullOrEmpty(id))
                    {
                        id = file;
                    }
                    var module = FindModule(id);
                    if (module == null)
                    {
                        module = new DebuggedModule(id, file, loadAddr, size, symsLoaded, symPath, _loadOrder++);
                        lock (_moduleList)
                        {
                            _moduleList.Add(module);
                        }
                        _callback.OnModuleLoad(module);
                    }
                }
            };

            if (_launchOptions is LocalLaunchOptions)
            {
                this.Init(new MICore.LocalTransport(), _launchOptions);
            }
            else if (_launchOptions is PipeLaunchOptions)
            {
                this.Init(new MICore.PipeTransport(), _launchOptions);
            }
            else if (_launchOptions is TcpLaunchOptions)
            {
                this.Init(new MICore.TcpTransport(), _launchOptions);
            }
            else if (_launchOptions is SerialLaunchOptions)
            {
                string port = ((SerialLaunchOptions)_launchOptions).Port;
                this.Init(new MICore.SerialTransport(port), _launchOptions);
            }
            else
            {
                throw new ArgumentOutOfRangeException("LaunchInfo.options");
            }

            MIDebugCommandDispatcher.AddProcess(this);

            // When the debuggee exits, we need to exit the debugger
            ProcessExitEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                ResultEventArgs results = args as MICore.Debugger.ResultEventArgs;

                if (results.Results.Contains("exit-code"))
                {
                    // GDB sometimes returns exit codes, which don't fit into uint, like "030000000472".
                    // And we can't throw from here, because it crashes VS.
                    // Full exit code will still usually be reported in the Output window,
                    // but here let's return "uint.MaxValue" just to indicate that something went wrong.
                    if (!uint.TryParse(results.Results.FindString("exit-code"), out processExitCode))
                    {
                        processExitCode = uint.MaxValue;
                    }
                }

                // quit MI Debugger
                _worker.PostOperation(CmdExitAsync);
                if (_waitDialog != null)
                {
                    _waitDialog.EndWaitDialog();
                }
            };

            // When the debugger exits, we tell AD7 we are done
            DebuggerExitEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                // this is the last AD7 Event we can ever send
                // Also the transport is closed when this returns
                _callback.OnProcessExit(processExitCode);

                Dispose();
            };

            DebuggerAbortedEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                // The MI debugger process unexpectedly exited.
                _worker.PostOperation(() =>
                {
                    // If the MI Debugger exits before we get a resume call, we have no way of sending program destroy. So just let start debugging fail.
                    if (!_connected)
                    {
                        return;
                    }

                    _callback.OnError(MICoreResources.Error_MIDebuggerExited);
                    _callback.OnProcessExit(uint.MaxValue);

                    Dispose();
                });
            };

            ModuleLoadEvent += async delegate(object o, EventArgs args)
            {
                // NOTE: This is an async void method, so make sure exceptions are caught and somehow reported

                if (_libraryLoaded.Count != 0)
                {
                    string moduleNames = string.Join(", ", _libraryLoaded);

                    try
                    {
                        _libraryLoaded.Clear();
                        SourceLineCache.OnLibraryLoad();

                        await _breakpointManager.BindAsync();
                        await CheckModules();

                        _bLastModuleLoadFailed = false;
                    }
                    catch (Exception e)
                    {
                        if (this.ProcessState == MICore.ProcessState.Exited)
                        {
                            return; // ignore exceptions after the process has exited
                        }

                        string exceptionDescription = EngineUtils.GetExceptionDescription(e);
                        string message = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_ExceptionProcessingModules, moduleNames, exceptionDescription);

                        // to avoid spamming the user, if the last module failed, we send the next failure to the output windiw instead of a message box
                        if (!_bLastModuleLoadFailed)
                        {
                            _callback.OnError(message);
                            _bLastModuleLoadFailed = true;
                        }
                        else
                        {
                            _callback.OnOutputMessage(new OutputMessage(message, enum_MESSAGETYPE.MT_OUTPUTSTRING, OutputMessage.Severity.Warning));
                        }
                    }
                }
                if (_waitDialog != null)
                {
                    _waitDialog.EndWaitDialog();
                }
                if (MICommandFactory.SupportsStopOnDynamicLibLoad())
                {
                    CmdContinueAsync();
                }
            };

            // When we break we need to gather information
            BreakModeEvent += async delegate(object o, EventArgs args)
            {
                // NOTE: This is an async void method, so make sure exceptions are caught and somehow reported

                ResultEventArgs results = args as MICore.Debugger.ResultEventArgs;
                if (_waitDialog != null)
                {
                    _waitDialog.EndWaitDialog();
                }

                if (!this._connected)
                {
                    _initialBreakArgs = results;
                    return;
                }

                try
                {
                    await HandleBreakModeEvent(results);
                }
                catch (Exception e)
                {
                    if (this.ProcessState == MICore.ProcessState.Exited)
                    {
                        return; // ignore exceptions after the process has exited
                    }

                    string exceptionDescription = EngineUtils.GetExceptionDescription(e);
                    string message = string.Format(CultureInfo.CurrentCulture, MICoreResources.Error_FailedToEnterBreakState, exceptionDescription);
                    _callback.OnError(message);

                    Terminate();
                }
            };

            ErrorEvent += delegate(object o, EventArgs args)
            {
                // NOTE: Exceptions leaked from this method may cause VS to crash, be careful

                ResultEventArgs result = (ResultEventArgs)args;
                _callback.OnError(result.Results.FindString("msg"));
            };

            ThreadCreatedEvent += delegate(object o, EventArgs args)
            {
                ResultEventArgs result = (ResultEventArgs)args;
                ThreadCache.ThreadEvent(result.Results.FindInt("id"), /*deleted */ false);
            };

            ThreadExitedEvent += delegate(object o, EventArgs args)
            {
                ResultEventArgs result = (ResultEventArgs)args;
                ThreadCache.ThreadEvent(result.Results.FindInt("id"), /*deleted*/ true);
            };

            MessageEvent += (object o, ResultEventArgs args) =>
            {
                OutputMessage outputMessage = DecodeOutputEvent(args.Results);
                if (outputMessage != null)
                {
                    _callback.OnOutputMessage(outputMessage);
                }
            };

            BreakChangeEvent += _breakpointManager.BreakpointModified;
        }
 public int WatchForProviderEvents(uint Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, ref Guid guidLaunchingEngine, IDebugPortNotify2 pEventCallback)
 {
     return(S_OK);
 }
示例#42
0
        public int GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess)
        {
            Log.Debug("ProgramProvider: GetProviderProcessData");

            if (Flags.HasFlag(enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES))
            {
                var process = Process.GetProcessById((int)ProcessId.dwProcessId);
                foreach (ProcessModule module in process.Modules)
                {
                    if (module.ModuleName.StartsWith("System.Management.Automation", StringComparison.OrdinalIgnoreCase))
                    {
                        var node = new ScriptProgramNode(new ScriptDebugProcess(pPort, ProcessId.dwProcessId));

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

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

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

                        return(VSConstants.S_OK);
                    }
                }
            }

            return(VSConstants.S_FALSE);
        }
 public int GetProviderProcessData(uint Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess)
 {
     return(S_FALSE);
 }
示例#44
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();

            // we handle creation of the remote program provider ourselves.  This is because we always load our program provider locally which keeps
            // attach working when developing Python Tools and running/debugging from within VS and in the experimental hive.  When we are installed
            // we install into the GAC so these types are available to create and then remote debugging works as well.  When we're running in the
            // experimental hive we are not in the GAC so if we're created outside of VS (e.g. in msvsmon on the local machine) then we can't get
            // at our program provider and debug->attach doesn't work.
            if (port != null && port.QueryIsLocal() == VSConstants.S_FALSE)
            {
                if (ErrorHandler.Succeeded(port.GetServer(out var server)))
                {
                    if (server is IDebugCoreServer90 dbgServer)
                    {
                        var g = typeof(IDebugProgramProvider2).GUID;

                        var hr = dbgServer.CreateManagedInstanceInServer(typeof(AD7ProgramProvider).FullName, typeof(AD7ProgramProvider).Assembly.FullName, 0, ref g, out var remoteProviderPunk);
                        try
                        {
                            if (ErrorHandler.Succeeded(hr))
                            {
                                var remoteProvider = (IDebugProgramProvider2)Marshal.GetObjectForIUnknown(remoteProviderPunk);
                                return(remoteProvider.GetProviderProcessData(Flags, null, ProcessId, EngineFilter, processArray));
                            }
                        }
                        finally
                        {
                            if (remoteProviderPunk != IntPtr.Zero)
                            {
                                Marshal.Release(remoteProviderPunk);
                            }
                        }
                    }
                }
            }
            else if ((Flags & enum_PROVIDER_FLAGS.PFLAG_GET_PROGRAM_NODES) != 0)
            {
                // The debugger is asking the engine to return the program nodes it can debug. We check
                // each process if it has a python##.dll or python##_d.dll loaded and if it does
                // then we report the program as being a Python process.

                /*
                 * if (DebugAttach.IsPythonProcess((int)ProcessId.dwProcessId)) {
                 *  IDebugProgramNode2 node = 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 VSConstants.S_OK;
                 * }*/
            }

            return(VSConstants.S_FALSE);
        }
示例#45
0
        public int Event(IDebugEngine2 engine, IDebugProcess2 process, IDebugProgram2 program, IDebugThread2 thread, IDebugEvent2 debugEvent, ref Guid riidEvent, uint attributes) {
            bool savedProgram = false;
            bool savedThread = false;

            if (riidEvent == processCreateEvent) {
                AD_PROCESS_ID[] pdwProcessId = new AD_PROCESS_ID[1];
                process.GetPhysicalProcessId(pdwProcessId);
                Debug.Assert(!this.attachedProcesses.Contains(pdwProcessId[0].dwProcessId));
                this.attachedProcesses.Add(pdwProcessId[0].dwProcessId);
            } else if (riidEvent == processDestroyEvent) {
                AD_PROCESS_ID[] pdwProcessId = new AD_PROCESS_ID[1];
                process.GetPhysicalProcessId(pdwProcessId);
                Debug.Assert(this.attachedProcesses.Contains(pdwProcessId[0].dwProcessId));
                this.attachedProcesses.Remove(pdwProcessId[0].dwProcessId);
            } else if (riidEvent == breakInEvent && this.currentDebugProgram != program && program != null && thread != null) {
                // Evaluate an expression get access to the memory context and the bitness.
                IDebugProperty2 debugProperty = this.EvaluateExpression(thread, "(void**)0x0 + 1");
                if (debugProperty != null) {
                    using (new DisposableComReference(debugProperty)) {
                        DEBUG_PROPERTY_INFO[] debugPropertyInfo = new DEBUG_PROPERTY_INFO[1];
                        if (debugProperty.GetPropertyInfo((uint)enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE, 16, evaluateExpressionTimeout, null, 0, debugPropertyInfo) == S_OK) {
                            IDebugMemoryContext2 memoryContext = null;
                            IDebugMemoryBytes2 memoryBytes = null;
                            if (debugProperty.GetMemoryContext(out memoryContext) == S_OK && debugProperty.GetMemoryBytes(out memoryBytes) == S_OK) {
                                DisposableComReference.SetReference(ref this.currentDebugProgram, program);
                                DisposableComReference.SetReference(ref this.currentThread, thread);
                                DisposableComReference.SetReference(ref this.memoryContext, memoryContext);
                                DisposableComReference.SetReference(ref this.memoryBytes, memoryBytes);
                                ulong offset = ulong.Parse(debugPropertyInfo[0].bstrValue.Substring("0x".Length), System.Globalization.NumberStyles.AllowHexSpecifier);

                                // Adjust the memory context and calculate the bitness.
                                this.memoryContext.Subtract(offset, out memoryContext);
                                DisposableComReference.SetReference(ref this.memoryContext, memoryContext);
                                this.isPointer64Bit = (offset == 8);

                                this.engine.NotifyDebuggerStatusChange(DebuggerChangeEventArgs.DebuggerStatus.Detaching);
                                this.engine.DiaLoader.ClearSymbols();
                                savedProgram = true;
                                savedThread = true;
                            } else {
                                DisposableComReference.ReleaseIfNotNull(ref memoryContext);
                                DisposableComReference.ReleaseIfNotNull(ref memoryBytes);
                            }
                        }
                    }
                }
            } else if (riidEvent == stopDebugEvent) {
                // The debugger stopped.  Clear the references.
                DisposableComReference.ReleaseIfNotNull(ref this.currentDebugProgram);
                DisposableComReference.ReleaseIfNotNull(ref this.memoryContext);
                DisposableComReference.ReleaseIfNotNull(ref this.memoryBytes);
                this.engine.NotifyDebuggerStatusChange(DebuggerChangeEventArgs.DebuggerStatus.Detaching);
                this.engine.DiaLoader.ClearSymbols();
            } else if (riidEvent == breakInEvent) {
                // The debugger broke in, notify the client.
                this.engine.NotifyDebuggerStatusChange(DebuggerChangeEventArgs.DebuggerStatus.Break);
            } else if (riidEvent == threadSwitchEvent) {
                // The user switched the current thread.
                DisposableComReference.SetReference(ref this.currentThread, thread);
                savedThread = true;
                if (this.currentThread != null) {
                    uint threadId;
                    thread.GetThreadId(out threadId);
                    this.TargetThreadSystemId = threadId;
                }

                bool processChanged = false;
                if (process != null) {
                    AD_PROCESS_ID[] pdwProcessId = new AD_PROCESS_ID[1];
                    process.GetPhysicalProcessId(pdwProcessId);
                    if (this.TargetProcessSystemId != 0) {
                        if (pdwProcessId[0].dwProcessId != this.TargetProcessSystemId) {
                            this.TargetProcessSystemId = pdwProcessId[0].dwProcessId;
                            processChanged = true;
                        }
                    } else {
                        this.TargetProcessSystemId = pdwProcessId[0].dwProcessId;
                        if (this.TargetProcessSystemId != 0) {
                            processChanged = true;
                        }
                    }
                } else if (this.TargetProcessSystemId != 0) {
                    this.TargetProcessSystemId = 0;
                    processChanged = true;
                }

                if (processChanged) {
                    DisposableComReference.SetReference(ref this.currentDebugProgram, program);
                    savedProgram = true;

                    if (program != null) {
                        // Evaluate an expression get access to the memory context and the bitness.
                        IDebugProperty2 debugProperty = this.EvaluateExpression(thread, "(void**)0x0 + 1");
                        if (debugProperty != null) {
                            using (new DisposableComReference(debugProperty)) {
                                DEBUG_PROPERTY_INFO[] debugPropertyInfo = new DEBUG_PROPERTY_INFO[1];
                                if (debugProperty.GetPropertyInfo((uint)enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_VALUE, 16, evaluateExpressionTimeout, null, 0, debugPropertyInfo) == S_OK) {
                                    IDebugMemoryContext2 memoryContext = null;
                                    IDebugMemoryBytes2 memoryBytes = null;
                                    if ((debugProperty.GetMemoryContext(out memoryContext) == S_OK) && (debugProperty.GetMemoryBytes(out memoryBytes) == S_OK)) {
                                        DisposableComReference.SetReference(ref this.memoryContext, memoryContext);
                                        DisposableComReference.SetReference(ref this.memoryBytes, memoryBytes);
                                        ulong offset = ulong.Parse(debugPropertyInfo[0].bstrValue.Substring("0x".Length), System.Globalization.NumberStyles.AllowHexSpecifier);

                                        // Adjust the memory context and calculate the bitness.
                                        this.memoryContext.Subtract(offset, out memoryContext);
                                        DisposableComReference.SetReference(ref this.memoryContext, memoryContext);
                                        this.isPointer64Bit = (offset == 8);
                                    } else {
                                        DisposableComReference.ReleaseIfNotNull(ref memoryContext);
                                        DisposableComReference.ReleaseIfNotNull(ref memoryBytes);
                                    }
                                }
                            }
                        }

                        this.engine.NotifyDebuggerStatusChange(DebuggerChangeEventArgs.DebuggerStatus.ChangingProcess);
                    }
                } else {
                    this.engine.NotifyDebuggerStatusChange(DebuggerChangeEventArgs.DebuggerStatus.ChangingThread);
                }
            }

            if (!savedProgram) {
                DisposableComReference.ReleaseIfNotNull(ref program);
            }
            if (!savedThread) {
                DisposableComReference.ReleaseIfNotNull(ref thread);
            }
            DisposableComReference.ReleaseIfNotNull(ref engine);
            DisposableComReference.ReleaseIfNotNull(ref process);
            DisposableComReference.ReleaseIfNotNull(ref debugEvent);

            return S_OK;
        }
示例#46
0
 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);
 }
示例#47
0
 int IDebugProgramProvider2.WatchForProviderEvents(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, ref Guid guidLaunchingEngine, IDebugPortNotify2 pEventCallback)
 {
     return(VSConstants.S_OK);
 }
示例#48
0
        // Establishes a callback to watch for provider events associated with specific kinds of processes
        int IDebugProgramProvider2.WatchForProviderEvents(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 port, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, ref Guid guidLaunchingEngine, IDebugPortNotify2 ad7EventCallback)
        {
            // The sample debug engine is a native debugger, and can therefore always provide a program node
            // in GetProviderProcessData. Non-native debuggers may wish to implement this method as a way
            // of monitoring the process before code for their runtime starts. For example, if implementing a
            // 'foo script' debug engine, one could attach to a process which might eventually run 'foo script'
            // before this 'foo script' started.
            //
            // To implement this method, an engine would monitor the target process and call AddProgramNode
            // when the target process started running code which was debuggable by the engine. The
            // enum_PROVIDER_FLAGS.PFLAG_ATTACHED_TO_DEBUGGEE flag indicates if the request is to start
            // or stop watching the process.

            return(VSConstants.S_OK);
        }
        // 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);
        }
示例#50
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);
 }
示例#51
0
        private CorDebugProcess GetProcess( AD_PROCESS_ID ProcessId )
        {                        
            AD_PROCESS_ID pid;                   

            foreach (CorDebugProcess process in m_alProcesses)
            {
                pid = process.PhysicalProcessId;

                if (AreProcessIdEqual(ProcessId, pid))
                {
                    return process;
                }
            }

            return null;
        }
示例#52
0
        int Microsoft.VisualStudio.Debugger.Interop.IDebugPort2.GetProcess(AD_PROCESS_ID ProcessId, out IDebugProcess2 ppProcess)
        {
            ppProcess = ((DebugPort)this).GetProcess(ProcessId);

            return(COM_HResults.BOOL_TO_HRESULT_FAIL(ppProcess != null));
        }
示例#53
0
        int Microsoft.VisualStudio.Debugger.Interop.IDebugPort2.GetProcess(AD_PROCESS_ID ProcessId, out IDebugProcess2 ppProcess)
        {
            ppProcess = ((DebugPort)this).GetProcess( ProcessId );

            return Utility.COM_HResults.BOOL_TO_HRESULT_FAIL( ppProcess != null );            
        }
示例#54
0
 public MonoProgramNode(AD_PROCESS_ID processId)
 {
     _processId = processId;
 }
示例#55
0
        /// <summary>
        /// Gets the system process identifier for the process hosting a program. (http://msdn.microsoft.com/en-us/library/bb162159.aspx)
        /// </summary>
        /// <param name="pHostProcessId"> Returns the system process identifier for the hosting process. </param>
        /// <returns> VSConstants.S_OK. </returns>
        public int GetHostPid(AD_PROCESS_ID[] pHostProcessId)
        {
            // According to the MSDN documentation (http://msdn.microsoft.com/en-us/library/bb162159.aspx),
            // it should return the process id of the hosting process, but what is expected is the program ID...
            pHostProcessId[0].ProcessIdType = (uint)enum_AD_PROCESS_ID.AD_PROCESS_ID_GUID;
            pHostProcessId[0].guidProcessId = m_processGuid;

            return VSConstants.S_OK;
        }
示例#56
0
 public int GetProcess(AD_PROCESS_ID ProcessId, out IDebugProcess2 ppProcess)
 {
     throw new NotImplementedException();
 }
示例#57
0
 public int GetHostId(AD_PROCESS_ID[] pProcessId)
 {
     throw new NotImplementedException();
 }
示例#58
0
 int IDebugProgramProvider2.GetProviderProcessData(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, CONST_GUID_ARRAY EngineFilter, PROVIDER_PROCESS_DATA[] pProcess)
 {
     throw new NotImplementedException();
 }
 // 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;
 }
示例#60
0
 int IDebugProgramProvider2.GetProviderProgramNode(enum_PROVIDER_FLAGS Flags, IDebugDefaultPort2 pPort, AD_PROCESS_ID ProcessId, ref Guid guidEngine, ulong programId, out IDebugProgramNode2 ppProgramNode)
 {
     throw new NotImplementedException();
 }