public DebuggerStartInfo CreateDebuggerStartInfo (ExecutionCommand command)
		{
			var cmd = (AspNetExecutionCommand) command;
			
			var runtime = (MonoTargetRuntime)cmd.TargetRuntime;
			var startInfo = new SoftDebuggerStartInfo (runtime.Prefix, runtime.EnvironmentVariables) {
				WorkingDirectory = cmd.BaseDirectory,
				Arguments = cmd.XspParameters.GetXspParameters ().Trim (),
			};
			
			var xspName = AspNetExecutionHandler.GetXspName (cmd);
			
			FilePath fxDir = GetFxDir (runtime, cmd.ClrVersion);
			FilePath xspPath = fxDir.Combine (xspName).ChangeExtension (".exe");
			
			//no idea why xsp is sometimes relocated to a "winhack" dir on Windows
			if (MonoDevelop.Core.PropertyService.IsWindows && !File.Exists (xspPath)) {
				var winhack = fxDir.Combine ("winhack");
				if (Directory.Exists (winhack))
					xspPath = winhack.Combine (xspName).ChangeExtension (".exe");
			}
			
			if (!File.Exists (xspPath))
				throw new UserException (GettextCatalog.GetString (
					"The \"{0}\" web server cannot be started. Please ensure that it is installed.", xspName), null);
			
			startInfo.Command = xspPath;
			
			string error;
			startInfo.UserAssemblyNames = SoftDebuggerEngine.GetAssemblyNames (cmd.UserAssemblyPaths, out error);
			startInfo.LogMessage = error;
			
			return startInfo;
		}
		public DebuggerStartInfo CreateDebuggerStartInfo (ExecutionCommand c)
		{
			var cmd = (DotNetExecutionCommand) c;
			var runtime = (MonoTargetRuntime)cmd.TargetRuntime;
			var dsi = new SoftDebuggerStartInfo (runtime.Prefix, runtime.EnvironmentVariables) {
				Command = cmd.Command,
				Arguments = cmd.Arguments,
				WorkingDirectory = cmd.WorkingDirectory,
			};
			
			string error;
			dsi.UserAssemblyNames = GetAssemblyNames (cmd.UserAssemblyPaths, out error);
			dsi.LogMessage = error;
			
			foreach (KeyValuePair<string,string> var in cmd.EnvironmentVariables)
				dsi.EnvironmentVariables [var.Key] = var.Value;
			
			var varsCopy = new Dictionary<string, string> (cmd.EnvironmentVariables);
			dsi.ExternalConsoleLauncher = delegate (System.Diagnostics.ProcessStartInfo info) {
				IProcessAsyncOperation oper;
				oper = Runtime.ProcessService.StartConsoleProcess (info.FileName, info.Arguments, info.WorkingDirectory,
					varsCopy, ExternalConsoleFactory.Instance.CreateConsole (dsi.CloseExternalConsoleOnExit), null);
				return new ProcessAdapter (oper, Path.GetFileName (info.FileName));
			};

			return dsi;
		}
		public override DebuggerStartInfo CreateDebuggerStartInfo (ExecutionCommand c)
		{
			var cmd = (DotNetExecutionCommand) c;
			var runtime = (MonoTargetRuntime)cmd.TargetRuntime;
			var dsi = new SoftDebuggerStartInfo (runtime.Prefix, runtime.EnvironmentVariables) {
				Command = cmd.Command,
				Arguments = cmd.Arguments,
				WorkingDirectory = cmd.WorkingDirectory,
			};
			
			SetUserAssemblyNames (dsi, cmd.UserAssemblyPaths);
			
			foreach (KeyValuePair<string,string> var in cmd.EnvironmentVariables)
				dsi.EnvironmentVariables [var.Key] = var.Value;
			
			var varsCopy = new Dictionary<string, string> (cmd.EnvironmentVariables);
			var startArgs = (SoftDebuggerLaunchArgs) dsi.StartArgs;
			startArgs.ExternalConsoleLauncher = delegate (System.Diagnostics.ProcessStartInfo info) {
				ProcessAsyncOperation oper;
				oper = Runtime.ProcessService.StartConsoleProcess (info.FileName, info.Arguments, info.WorkingDirectory,
					ExternalConsoleFactory.Instance.CreateConsole (dsi.CloseExternalConsoleOnExit), varsCopy);
				return new ProcessAdapter (oper, Path.GetFileName (info.FileName));
			};
			startArgs.MonoExecutableFileName = runtime.MonoRuntimeInfo.Force64or32bit.HasValue ? runtime.MonoRuntimeInfo.Force64or32bit.Value ? "mono64" : "mono32" : "mono";
			return dsi;
		}
		public DebuggerStartInfo CreateDebuggerStartInfo (ExecutionCommand command)
		{
			var cmd = (AspNetExecutionCommand) command;
			
			var runtime = (MonoTargetRuntime)cmd.TargetRuntime;
			var startInfo = new SoftDebuggerStartInfo (runtime.Prefix, runtime.EnvironmentVariables) {
				WorkingDirectory = cmd.BaseDirectory,
				Arguments = cmd.XspParameters.GetXspParameters ().Trim (),
			};
			
			FilePath prefix = runtime.Prefix;
			if (MonoDevelop.Core.PropertyService.IsWindows) {
				startInfo.Command = (cmd.ClrVersion == ClrVersion.Net_1_1)
					? prefix.Combine ("lib", "mono", "1.0", "winhack", "xsp.exe")
					: prefix.Combine ("lib", "mono", "2.0", "winhack", "xsp2.exe");
			}
			else {
				startInfo.Command = (cmd.ClrVersion == ClrVersion.Net_1_1)
					? prefix.Combine ("lib", "mono", "1.0", "xsp.exe")
					: prefix.Combine ("lib", "mono", "2.0", "xsp2.exe");
			}
			
			string error;
			startInfo.UserAssemblyNames = SoftDebuggerEngine.GetAssemblyNames (cmd.UserAssemblyPaths, out error);
			startInfo.LogMessage = error;
			
			return startInfo;
		}
		public DebuggerStartInfo CreateDebuggerStartInfo (ExecutionCommand command)
		{
			var cmd = (AspNetExecutionCommand) command;
			var evars = new Dictionary<string, string>(cmd.EnvironmentVariables);
			var runtime = (MonoTargetRuntime) cmd.TargetRuntime;

			foreach (var v in runtime.EnvironmentVariables)
			{
				if (!evars.ContainsKey (v.Key))
					evars.Add (v.Key, v.Value);
			}
			
			var startInfo = new SoftDebuggerStartInfo (runtime.Prefix, evars) {
				WorkingDirectory = cmd.BaseDirectory,
				Arguments = cmd.XspParameters.GetXspParameters ().Trim (),
			};
			
			var xspName = AspNetExecutionHandler.GetXspName (cmd);
			
			FilePath fxDir = GetFxDir (runtime, cmd.ClrVersion);
			FilePath xspPath = fxDir.Combine (xspName).ChangeExtension (".exe");
			
			//no idea why xsp is sometimes relocated to a "winhack" dir on Windows
			if (MonoDevelop.Core.Platform.IsWindows && !File.Exists (xspPath)) {
				var winhack = fxDir.Combine ("winhack");
				if (Directory.Exists (winhack))
					xspPath = winhack.Combine (xspName).ChangeExtension (".exe");
			}
			
			if (!File.Exists (xspPath))
				throw new UserException (GettextCatalog.GetString (
					"The \"{0}\" web server cannot be started. Please ensure that it is installed.", xspName), null);
			
			startInfo.Command = xspPath;
			SoftDebuggerEngine.SetUserAssemblyNames (startInfo, cmd.UserAssemblyPaths);
			
			return startInfo;
		}
		/// <summary>Starts the debugger listening for a connection over TCP/IP</summary>
		protected void StartListening (SoftDebuggerStartInfo dsi)
		{
			int dp, cp;
			StartListening (dsi, out dp, out cp);
		}
Example #7
0
		public static void Run(FileInfo file)
		{
			lock (_lock)
			{
				EnsureCreated();

				CurrentExecutable = file;
				CurrentAddress = null;
				CurrentPort = -1;

				_debuggeeKilled = false;
				_kind = SessionKind.Launched;

				var info = new SoftDebuggerStartInfo(Configuration.Current.RuntimePrefix,
					new Dictionary<string, string>(EnvironmentVariables))
				{
					Command = file.FullName,
					Arguments = Arguments,
					WorkingDirectory = WorkingDirectory,
					StartArgs =
					{
						MaxConnectionAttempts = Configuration.Current.MaxConnectionAttempts,
						TimeBetweenConnectionAttempts = Configuration.Current.ConnectionAttemptInterval
					}
				};

				// We need to ignore `SIGINT` while we start the inferior
				// process so that it inherits that signal disposition.
				CommandLine.UnsetControlCHandler();

				_session.Run(info, Options);

				CommandLine.InferiorExecuting = true;
			}
		}
Example #8
0
        public SoftDebuggerStartInfo DebuggerInfo(int consolePort = -1)
        {
            try
            {

                IPAddress[] addresslist = Dns.GetHostAddresses(LocalHost);

                var	startArgs = new SoftDebuggerConnectArgs ("", addresslist[0], (int)LocalTunnelPort, consolePort) {
                        //infinite connection retries (user can cancel), 800ms between them
                        TimeBetweenConnectionAttempts = 800,
                        MaxConnectionAttempts = -1,
                };

                var dsi = new SoftDebuggerStartInfo (startArgs) {
                        Command = "",
                        Arguments = ""
                };

                if (Terminal != null) Terminal.SSH.WriteLine ("Configuring debugger {0}:{1}",addresslist[0], (int)LocalTunnelPort);

                return dsi;

            }
            catch (Exception ex)
            {

                if (Terminal != null) {
                    Terminal.SSH.WriteLine ("SoftDebuggerStartInfo Error {0}", ex.Message);
                } else {
                    Gtk.Application.Invoke (delegate {
                        using (var md = new MessageDialog (null, DialogFlags.Modal, MessageType.Info, ButtonsType.Ok, String.Format("SoftDebuggerStartInfo Error {0}", ex.Message))) {
                            md.Title = "ProcessScript";
                            md.Run ();
                            md.Destroy ();
                        }
                    });
                }
                return null;
            }
        }
		void RegisterUserAssemblies (SoftDebuggerStartInfo dsi)
		{
			if (Options.ProjectAssembliesOnly && dsi.UserAssemblyNames != null) {
				assemblyFilters = new List<AssemblyMirror> ();
				userAssemblyNames = dsi.UserAssemblyNames.Select (x => x.ToString ()).ToList ();
			}
			
			assemblyPathMap = dsi.AssemblyPathMap;
			if (assemblyPathMap == null)
				assemblyPathMap = new Dictionary<string, string> ();
		}
		void InitForRemoteSession (SoftDebuggerStartInfo dsi, out IPEndPoint dbgEP, out IPEndPoint conEP)
		{
			if (remoteProcessName != null)
				throw new InvalidOperationException ("Cannot initialize connection more than once");
			
			var args = (SoftDebuggerRemoteArgs) dsi.StartArgs;
			
			remoteProcessName = args.AppName;
			
			RegisterUserAssemblies (dsi);
			
			dbgEP = new IPEndPoint (args.Address, args.DebugPort);
			conEP = args.RedirectOutput? new IPEndPoint (args.Address, args.OutputPort) : null;
			
			if (!String.IsNullOrEmpty (dsi.LogMessage))
				LogWriter (false, dsi.LogMessage + "\n");
		}
		/// <summary>Starts the debugger connecting to a remote IP</summary>
		protected void StartConnecting (SoftDebuggerStartInfo dsi, int maxAttempts, int timeBetweenAttempts)
		{	
			if (timeBetweenAttempts < 0 || timeBetweenAttempts > 10000)
				throw new ArgumentException ("timeBetweenAttempts");
			
			IPEndPoint dbgEP, conEP;
			InitForRemoteSession (dsi, out dbgEP, out conEP);
			
			AsyncCallback callback = null;
			int attemptNumber = 0;
			callback = delegate (IAsyncResult ar) {
				try {
					ConnectionStarted (VirtualMachineManager.EndConnect (ar));
					return;
				} catch (Exception ex) {
					attemptNumber++;
					if (!ShouldRetryConnection (ex, attemptNumber) || attemptNumber == maxAttempts || Exited) {
						OnConnectionError (ex);
						return;
					}
				}
				try {
					if (timeBetweenAttempts > 0)
						System.Threading.Thread.Sleep (timeBetweenAttempts);
					
					ConnectionStarting (VirtualMachineManager.BeginConnect (dbgEP, conEP, callback), dsi, false, attemptNumber);
					
				} catch (Exception ex2) {
					OnConnectionError (ex2);
				}
			};
			
			ConnectionStarting (VirtualMachineManager.BeginConnect (dbgEP, conEP, callback), dsi, false, 0);
		}
		protected void StartConnecting (SoftDebuggerStartInfo dsi)
		{
			StartConnecting (dsi, dsi.StartArgs.MaxConnectionAttempts, dsi.StartArgs.TimeBetweenConnectionAttempts);
		}
		/// <summary>Starts the debugger listening for a connection over TCP/IP</summary>
		protected void StartListening (SoftDebuggerStartInfo dsi,
			out int assignedDebugPort, out int assignedConsolePort)
		{
		
			IPEndPoint dbgEP, conEP;
			InitForRemoteSession (dsi, out dbgEP, out conEP);
			
			var callback = HandleConnectionCallbackErrors (delegate (IAsyncResult ar) {
				ConnectionStarted (VirtualMachineManager.EndListen (ar));
			});
			var a = VirtualMachineManager.BeginListen (dbgEP, conEP, callback, out assignedDebugPort, out assignedConsolePort);
			ConnectionStarting (a, dsi, true, 0);
		}
		/// <summary>Starts the debugger listening for a connection over TCP/IP</summary>
		protected void StartListening (SoftDebuggerStartInfo dsi, out int assignedDebugPort)
		{
			int cp;
			StartListening (dsi, out assignedDebugPort, out cp);
		}
		void StartLaunching (SoftDebuggerStartInfo dsi)
		{
			var args = (SoftDebuggerLaunchArgs) dsi.StartArgs;
			var runtime = Path.Combine (Path.Combine (args.MonoRuntimePrefix, "bin"), "mono");
			RegisterUserAssemblies (dsi);
			
			var psi = new System.Diagnostics.ProcessStartInfo (runtime) {
				Arguments = string.Format ("\"{0}\" {1}", dsi.Command, dsi.Arguments),
				WorkingDirectory = dsi.WorkingDirectory,
				RedirectStandardOutput = true,
				RedirectStandardError = true,
				UseShellExecute = false,
				CreateNoWindow = true,
			};
			
			LaunchOptions options = null;
			
			if (dsi.UseExternalConsole && args.ExternalConsoleLauncher != null) {
				options = new LaunchOptions ();
				options.CustomTargetProcessLauncher = args.ExternalConsoleLauncher;
				psi.RedirectStandardOutput = false;
				psi.RedirectStandardError = false;
			}

			var sdbLog = Environment.GetEnvironmentVariable ("MONODEVELOP_SDB_LOG");
			if (!String.IsNullOrEmpty (sdbLog)) {
				options = options ?? new LaunchOptions ();
				options.AgentArgs = string.Format ("loglevel=1,logfile='{0}'", sdbLog);
			}
			
			foreach (var env in args.MonoRuntimeEnvironmentVariables)
				psi.EnvironmentVariables[env.Key] = env.Value;
			
			foreach (var env in dsi.EnvironmentVariables)
				psi.EnvironmentVariables[env.Key] = env.Value;
			
			if (!String.IsNullOrEmpty (dsi.LogMessage))
				OnDebuggerOutput (false, dsi.LogMessage + "\n");
			
			var callback = HandleConnectionCallbackErrors ((IAsyncResult ar) => {
				ConnectionStarted (VirtualMachineManager.EndLaunch (ar));
			});
			ConnectionStarting (VirtualMachineManager.BeginLaunch (psi, callback, options), dsi, true, 0);
		}
		void StartConnection (SoftDebuggerStartInfo dsi)
		{
			this.startArgs = dsi.StartArgs;
			
			RegisterUserAssemblies (dsi);
			
			if (!String.IsNullOrEmpty (dsi.LogMessage))
				LogWriter (false, dsi.LogMessage + "\n");
			
			AsyncCallback callback = null;
			int attemptNumber = 0;
			int maxAttempts = startArgs.MaxConnectionAttempts;
			int timeBetweenAttempts = startArgs.TimeBetweenConnectionAttempts;
			callback = delegate (IAsyncResult ar) {
				try {
					string appName;
					VirtualMachine vm;
					startArgs.ConnectionProvider.EndConnect (ar, out vm, out appName);
					this.remoteProcessName = appName;
					ConnectionStarted (vm);
					return;
				} catch (Exception ex) {
					attemptNumber++;
					if (!ShouldRetryConnection (ex, attemptNumber)
						|| !startArgs.ConnectionProvider.ShouldRetryConnection (ex)
						|| attemptNumber == maxAttempts
						|| Exited)
					{
						OnConnectionError (ex);
						return;
					}
				}
				try {
					if (timeBetweenAttempts > 0)
						System.Threading.Thread.Sleep (timeBetweenAttempts);
					ConnectionStarting (startArgs.ConnectionProvider.BeginConnect (dsi, callback), dsi, false, 0);
				} catch (Exception ex2) {
					OnConnectionError (ex2);
				}
			};
			//the "listening" value is never used, pass a dummy value
			ConnectionStarting (startArgs.ConnectionProvider.BeginConnect (dsi, callback), dsi, false, 0);
		}
		protected void StartConnecting (SoftDebuggerStartInfo dsi)
		{
			var args = (SoftDebuggerConnectArgs) dsi.StartArgs;
			StartConnecting (dsi, args.MaxConnectionAttempts, args.TimeBetweenConnectionAttempts);
		}
		public static void SetUserAssemblyNames (SoftDebuggerStartInfo dsi, IList<string> files)
		{
			if (files == null || files.Count == 0)
				return;
			
			var pathMap = new Dictionary<string, string> ();
			var names = new List<AssemblyName> ();
			
			foreach (var file in files) {
				if (!File.Exists (file)) {
					dsi.LogMessage = GettextCatalog.GetString ("User assembly '{0}' is missing. " +
						"Debugger will now debug all code, not just user code.", file);
					continue;
				}
				
				try {
					var asm = Mono.Cecil.AssemblyDefinition.ReadAssembly (file);
					if (string.IsNullOrEmpty (asm.Name.Name))
						throw new InvalidOperationException ("Assembly has no assembly name");
					
					AssemblyName name = new AssemblyName (asm.Name.FullName);
					if (!pathMap.ContainsKey (asm.Name.FullName))
						pathMap.Add (asm.Name.FullName, file);
					names.Add (name);
				} catch (Exception ex) {
					dsi.LogMessage = GettextCatalog.GetString ("Could not get assembly name for user assembly '{0}'. " +
						"Debugger will now debug all code, not just user code.", file);
					LoggingService.LogError ("Error getting assembly name for user assembly '" + file + "'", ex);
					continue;
				}
			}
			
			dsi.UserAssemblyNames = names;
			dsi.AssemblyPathMap = pathMap;
		}
Example #19
0
        public bool CreateSession(ValueReference startInfo, EvaluationOptions ops)
        {
            // Get the exe and arguments from the start info and store them
            this.arguments = (string)startInfo.GetChild("Arguments", ops).GetRawValue(ops);
            this.exe       = (string)startInfo.GetChild("FileName", ops).GetRawValue(ops);

            // Create the new session and custom start arguments.
            // The actual arguments don't matter much since we'll use a custom launcher for the process.
            newSession = new SoftDebuggerSession();

            var startArgs = new SoftDebuggerLaunchArgs(null, new Dictionary <string, string> ());
            var dsi       = new SoftDebuggerStartInfo(startArgs);

            // A mono process can be launched either by providing "mono" as launcher and then the assembly name as argument,
            // or by providing the assembly name directly as file to launch.

            bool explicitMonoLaunch = IsMonoLauncher(exe);

            if (explicitMonoLaunch)
            {
                // Try to get the assembly name from the command line. The debug session uses what's provided
                // in the Command property as process name. Without this, all mono processes launched in this
                // way would show up as "mono" in the IDE.
                var cmd = GetExeName(arguments);
                if (cmd != null)
                {
                    dsi.Command = cmd;
                }

                // The new session will add additional runtime arguments to the start info.
                // We'll use the _ARG_START_ marker to know where those arguments end.
                dsi.RuntimeArguments = ArgStartMarker;
            }
            else
            {
                dsi.Command   = exe;
                dsi.Arguments = arguments;
            }

            startArgs.CustomProcessLauncher = TargetProcessLauncher;

            // Start the session. This will run asynchronously, and will at some point call the custom launcher specified just above.
            newSession.Run(dsi, softDebuggerSession.Options);

            // Wait for the session to ask for the process to be launched
            launchingEvent.WaitOne();
            if (shutdown)
            {
                return(false);
            }

            // The custom launcher will store the debugger agent configuration args in debuggerStartInfo.
            // No the original startInfo object is patched to include the debugger agent args

            if (explicitMonoLaunch)
            {
                // Prepend the debugger args to the original arguments
                int i            = debuggerStartInfo.Arguments.IndexOf(ArgStartMarker);
                var debuggerArgs = debuggerStartInfo.Arguments.Substring(0, i);
                startInfo.GetChild("Arguments", ops).SetRawValue(debuggerArgs + " " + arguments, ops);
            }
            else
            {
                startInfo.GetChild("Arguments", ops).SetRawValue(debuggerStartInfo.Arguments, ops);
                startInfo.GetChild("FileName", ops).SetRawValue(debuggerStartInfo.FileName, ops);
            }
            return(true);
        }