Inheritance: Mono.Debugging.Client.DebuggerSession
コード例 #1
0
        public SoftEvaluationContext(SoftDebuggerSession session, StackFrame frame, DC.EvaluationOptions options)
            : base(options)
        {
            Frame = frame;
            Thread = frame.Thread;
            Domain = frame.Domain;

            string method = frame.Method.Name;
            if (frame.Method.DeclaringType != null)
                method = frame.Method.DeclaringType.FullName + "." + method;
            var location = new DC.SourceLocation (method, frame.FileName, frame.LineNumber, frame.ColumnNumber, frame.EndLineNumber, frame.EndColumnNumber, frame.Location.SourceFileHash);
            string language;

            if (frame.Method != null) {
                language = frame.IsNativeTransition ? "Transition" : "Managed";
            } else {
                language = "Native";
            }

            Evaluator = session.GetEvaluator (new DC.StackFrame (frame.ILOffset, location, language, session.IsExternalCode (frame), true));
            Adapter = session.Adaptor;
            this.session = session;
            stackVersion = session.StackVersion;
            sourceAvailable = !string.IsNullOrEmpty (frame.FileName) && System.IO.File.Exists (frame.FileName);
        }
コード例 #2
0
        public SoftEvaluationContext(SoftDebuggerSession session, StackFrame frame, DC.EvaluationOptions options) : base(options)
        {
            Frame  = frame;
            Thread = frame.Thread;
            Domain = Thread.Domain;

            string method = frame.Method.Name;

            if (frame.Method.DeclaringType != null)
            {
                method = frame.Method.DeclaringType.FullName + "." + method;
            }
            var    location = new DC.SourceLocation(method, frame.FileName, frame.LineNumber, frame.ColumnNumber);
            string language;

            if (frame.Method != null)
            {
                language = frame.IsNativeTransition ? "Transition" : "Managed";
            }
            else
            {
                language = "Native";
            }

            Evaluator       = session.GetEvaluator(new DC.StackFrame(frame.ILOffset, location, language, session.IsExternalCode(frame), true));
            Adapter         = session.Adaptor;
            this.session    = session;
            stackVersion    = session.StackVersion;
            sourceAvailable = !string.IsNullOrEmpty(frame.FileName) && System.IO.File.Exists(frame.FileName);
        }
コード例 #3
0
        public override void CopyFrom(EvaluationContext ctx)
        {
            base.CopyFrom(ctx);
            SoftEvaluationContext other = (SoftEvaluationContext)ctx;

            frame        = other.frame;
            stackVersion = other.stackVersion;
            Thread       = other.Thread;
            session      = other.session;
        }
コード例 #4
0
		public SoftDebuggerBacktrace (SoftDebuggerSession session, MDB.ThreadMirror thread): base (session.Adaptor)
		{
			this.session = session;
			this.thread = thread;
			stackVersion = session.StackVersion;
			if (thread != null)
				this.frames = thread.GetFrames ();
			else
				this.frames = new MDB.StackFrame[0];
		}
コード例 #5
0
        DC.StackFrame CreateStackFrame(MDB.StackFrame frame)
        {
            string method = frame.Method.Name;

            if (frame.Method.DeclaringType != null)
            {
                method = frame.Method.DeclaringType.FullName + "." + method;
            }
            var location = new DC.SourceLocation(method, SoftDebuggerSession.NormalizePath(frame.FileName), frame.LineNumber);
            var lang     = frame.Method != null? "Managed" : "Native";

            return(new DC.StackFrame(frame.ILOffset, frame.Method.FullName, location, lang, session.IsExternalCode(frame), true));
        }
コード例 #6
0
 public SoftDebuggerBacktrace(SoftDebuggerSession session, MDB.ThreadMirror thread) : base(session.Adaptor)
 {
     this.session = session;
     this.thread  = thread;
     stackVersion = session.StackVersion;
     if (thread != null)
     {
         this.frames = thread.GetFrames();
     }
     else
     {
         this.frames = new MDB.StackFrame[0];
     }
 }
コード例 #7
0
		public SoftEvaluationContext (SoftDebuggerSession session, StackFrame frame, DC.EvaluationOptions options): base (options)
		{
			Frame = frame;
			Thread = frame.Thread;

			string method = frame.Method.Name;
			if (frame.Method.DeclaringType != null)
				method = frame.Method.DeclaringType.FullName + "." + method;
			var location = new DC.SourceLocation (method, frame.FileName, frame.LineNumber);
			var lang = frame.Method != null? "Managed" : "Native";
			
			Evaluator = session.GetEvaluator (new DC.StackFrame (frame.ILOffset, location, lang, session.IsExternalCode (frame), true));
			Adapter = session.Adaptor;
			this.session = session;
			this.stackVersion = session.StackVersion;
			sourceAvailable = !string.IsNullOrEmpty (frame.FileName) && System.IO.File.Exists (frame.FileName);
		}
コード例 #8
0
        public SoftEvaluationContext(SoftDebuggerSession session, StackFrame frame, DC.EvaluationOptions options) : base(options)
        {
            Frame  = frame;
            Thread = frame.Thread;


            string method = frame.Method.Name;

            if (frame.Method.DeclaringType != null)
            {
                method = frame.Method.DeclaringType.FullName + "." + method;
            }
            var location = new DC.SourceLocation(method, frame.FileName, frame.LineNumber);
            var lang     = frame.Method != null? "Managed" : "Native";

            Evaluator         = session.GetResolver(new DC.StackFrame(frame.ILOffset, location, lang, session.IsExternalCode(frame), true));
            Adapter           = session.Adaptor;
            this.session      = session;
            this.stackVersion = session.StackVersion;
        }
コード例 #9
0
		public override void CopyFrom (EvaluationContext ctx)
		{
			base.CopyFrom (ctx);
			SoftEvaluationContext other = (SoftEvaluationContext) ctx;
			frame = other.frame;
			stackVersion = other.stackVersion;
			Thread = other.Thread;
			session = other.session;
		}
コード例 #10
0
		public static void Kill()
		{
			lock (_lock)
			{
				if (_session == null)
					return;

				CommandLine.InferiorExecuting = true;

				if (!_session.HasExited)
					_session.Exit();

				_session.Dispose();
				_session = null;
			}
		}
コード例 #11
0
		public static void Disconnect()
		{
			lock (_lock)
			{
				if (_session == null)
					return;

				CommandLine.InferiorExecuting = true;

				_kind = SessionKind.Disconnected;

				Breakpoints.Clear();
				BreakEvents.Clear();

				_session.Continue();

				_session = null;
			}
		}
コード例 #12
0
		static void EnsureCreated()
		{
			lock (_lock)
			{
				if (_session != null)
					return;

				_session = new SoftDebuggerSession();
				_session.Breakpoints = BreakEvents;

				_session.ExceptionHandler = ex =>
				{
					if (Configuration.Current.LogInternalErrors)
					{
						Log.Error("Internal debugger error:", ex.GetType());
						Log.Error(ex.ToString());
					}

					return true;
				};

				_session.LogWriter = (isStdErr, text) =>
				{
					if (Configuration.Current.LogRuntimeSpew)
						Log.NoticeSameLine("[Mono] {0}", text); // The string already has a line feed.
				};

				_session.OutputWriter = (isStdErr, text) =>
				{
					//lock (Log.Lock)
					//{
						if (Callback != null)
						{
							Callback.Invoke(isStdErr ? "ErrorOutput" : "Output", null, null, text);
						}
						else
						{
							if (isStdErr)
								Console.Error.Write(text);
							else
								Console.Write(text);
						}
					//}
				};

				_session.TypeResolverHandler += (identifier, location) =>
				{
					// I honestly have no idea how correct this is. I suspect you
					// could probably break it in some corner cases. It does make
					// something like `p Android.Runtime.JNIEnv.Handle` work,
					// though, which would otherwise have required `global::` to
					// be explicitly prepended.

					if (identifier == "__EXCEPTION_OBJECT__")
						return null;

					foreach (var loc in ActiveFrame.GetAllLocals())
						if (loc.Name == identifier)
							return null;

					return identifier;
				};

				_session.TargetEvent += (sender, e) =>
				{
					Log.Debug("Event: '{0}'", e.Type);
				};

				_session.TargetStarted += (sender, e) =>
				{
					_activeFrame = null;

					/*
					if (_showResumeMessage)
						Log.Notice("Inferior process '{0}' ('{1}') resumed",
							ActiveProcess.Id, StringizeTarget());
					*/
				};

				_session.TargetReady += (sender, e) =>
				{
					_activeProcess = _session.GetProcesses().SingleOrDefault();

					// The inferior process has launched, so we can safely
					// set our `SIGINT` handler without it interfering with
					// the inferior.
					CommandLine.SetControlCHandler();

					/*
					Log.Notice("Inferior process '{0}' ('{1}') started",
						ActiveProcess.Id, StringizeTarget());
					*/
				};

				_session.TargetStopped += (sender, e) =>
				{
					//Log.Notice("Inferior process '{0}' ('{1}') suspended",
					//	ActiveProcess.Id, StringizeTarget());
					//Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true));

					if (Callback != null)
					{
						Callback.Invoke("TargetStopped", ActiveFrame.SourceLocation, e.Thread, null);
					}

					CommandLine.ResumeEvent.Set();
				};

				_session.TargetInterrupted += (sender, e) =>
				{
					Log.Notice("Inferior process '{0}' ('{1}') interrupted",
						ActiveProcess.Id, StringizeTarget());
					Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true));

					CommandLine.ResumeEvent.Set();
				};

				_session.TargetHitBreakpoint += (sender, e) =>
				{
					// var bp = e.BreakEvent as Breakpoint;
					// var fbp = e.BreakEvent as FunctionBreakpoint;

					/*
					if (fbp != null)
						Log.Notice("Hit method breakpoint on '{0}'", fbp.FunctionName);
					else
					{
						var cond = bp.ConditionExpression != null ?
							string.Format(" (condition '{0}' met)", bp.ConditionExpression) :
							string.Empty;

						Log.Notice("Hit breakpoint at '{0}:{1}'{2}", bp.FileName, bp.Line, cond);
					}

					Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true));
					*/

					if (Callback != null)
					{
						Callback.Invoke("TargetHitBreakpoint", ActiveFrame.SourceLocation, e.Thread, null);
					}

					CommandLine.ResumeEvent.Set();
				};

				_session.TargetExited += (sender, e) =>
				{
					var p = ActiveProcess;

					/*
					// Can happen when a remote connection attempt fails.
					if (p == null)
					{
						if (_kind == SessionKind.Listening)
							Log.Notice("Listening socket closed");
						else if (_kind == SessionKind.Connected)
							Log.Notice("Connection attempt terminated");
						else
							Log.Notice("Failed to connect to '{0}'", StringizeTarget());
					}
					else
						Log.Notice("Inferior process '{0}' ('{1}') exited", ActiveProcess.Id, StringizeTarget());
					*/

					// Make sure we clean everything up on a normal exit.
					Kill();

					_debuggeeKilled = true;
					_kind = SessionKind.Disconnected;

					if (Callback != null)
					{
						Callback.Invoke("TargetExited", null, null, null);
					}

					CommandLine.ResumeEvent.Set();
				};

				_session.TargetExceptionThrown += (sender, e) =>
				{
					var ex = ActiveException;

					//Log.Notice("Trapped first-chance exception of type '{0}'", ex.Type);
					//Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true));

					PrintException(ex);

					if (Callback != null)
					{
						Callback.Invoke("TargetExceptionThrown", ActiveFrame.SourceLocation, e.Thread, null);
					}

					CommandLine.ResumeEvent.Set();
				};

				_session.TargetUnhandledException += (sender, e) =>
				{
					var ex = ActiveException;

					//Log.Notice("Trapped unhandled exception of type '{0}'", ex.Type);
					//Log.Emphasis(Utilities.StringizeFrame(ActiveFrame, true));

					PrintException(ex);

					if (Callback != null)
					{
						Callback.Invoke("TargetUnhandledException", ActiveFrame.SourceLocation, e.Thread, null);
					}

					CommandLine.ResumeEvent.Set();
				};

				_session.TargetThreadStarted += (sender, e) =>
				{
					//Log.Notice("Inferior thread '{0}' ('{1}') started",
					//	e.Thread.Id, e.Thread.Name);

					if (Callback != null)
					{
						Callback.Invoke("TargetThreadStarted", null, e.Thread, null);
					}
				};

				_session.TargetThreadStopped += (sender, e) =>
				{
					//Log.Notice("Inferior thread '{0}' ('{1}') exited",
					//	e.Thread.Id, e.Thread.Name);

					if (Callback != null)
					{
						Callback.Invoke("TargetThreadStopped", null, e.Thread, null);
					}
				};
			}
		}
コード例 #13
0
        DC.StackFrame CreateStackFrame(MDB.StackFrame frame, int frameIndex)
        {
            MDB.MethodMirror method       = frame.Method;
            MDB.TypeMirror   type         = method.DeclaringType;
            string           fileName     = frame.FileName;
            string           typeFullName = null;
            string           typeFQN      = null;
            string           methodName;

            if (fileName != null)
            {
                fileName = SoftDebuggerSession.NormalizePath(fileName);
            }

            if (method.VirtualMachine.Version.AtLeast(2, 12) && method.IsGenericMethod)
            {
                StringBuilder name = new StringBuilder(method.Name);

                name.Append('<');

                if (method.VirtualMachine.Version.AtLeast(2, 15))
                {
                    bool first = true;

                    foreach (var argumentType in method.GetGenericArguments())
                    {
                        if (!first)
                        {
                            name.Append(", ");
                        }

                        name.Append(session.Adaptor.GetDisplayTypeName(argumentType.FullName));
                        first = false;
                    }
                }

                name.Append('>');

                methodName = name.ToString();
            }
            else
            {
                methodName = method.Name;
            }

            if (string.IsNullOrEmpty(methodName))
            {
                methodName = "[Function Without Name]";
            }

            // Compiler generated anonymous/lambda methods
            bool special_method = false;

            if (methodName [0] == '<' && methodName.Contains(">m__"))
            {
                int nidx = methodName.IndexOf(">m__", StringComparison.Ordinal) + 2;
                methodName     = "AnonymousMethod" + methodName.Substring(nidx, method.Name.Length - nidx);
                special_method = true;
            }

            if (type != null)
            {
                string typeDisplayName = session.Adaptor.GetDisplayTypeName(type.FullName);

                if (SoftDebuggerAdaptor.IsGeneratedType(type))
                {
                    // The user-friendly method name is embedded in the generated type name
                    var mn = SoftDebuggerAdaptor.GetNameFromGeneratedType(type);

                    // Strip off the generated type name
                    int dot   = typeDisplayName.LastIndexOf('.');
                    var tname = typeDisplayName.Substring(0, dot);

                    // Keep any type arguments
                    int targs = typeDisplayName.LastIndexOf('<');
                    if (targs > dot + 1)
                    {
                        mn += typeDisplayName.Substring(targs, typeDisplayName.Length - targs);
                    }

                    typeDisplayName = tname;

                    if (special_method)
                    {
                        typeDisplayName += "." + mn;
                    }
                    else
                    {
                        methodName = mn;
                    }
                }

                methodName = typeDisplayName + "." + methodName;

                typeFQN      = type.Module.FullyQualifiedName;
                typeFullName = type.FullName;
            }
            bool external = false;
            bool hidden   = false;

            if (session.VirtualMachine.Version.AtLeast(2, 21))
            {
                var ctx        = GetEvaluationContext(frameIndex, session.EvaluationOptions);
                var hiddenAttr = session.Adaptor.GetType(ctx, "System.Diagnostics.DebuggerHiddenAttribute") as MDB.TypeMirror;
                hidden = method.GetCustomAttributes(hiddenAttr, true).Any();
            }
            if (hidden)
            {
                external = true;
            }
            else
            {
                external = session.IsExternalCode(frame);
                if (!external && session.Options.ProjectAssembliesOnly && session.VirtualMachine.Version.AtLeast(2, 21))
                {
                    var ctx             = GetEvaluationContext(frameIndex, session.EvaluationOptions);
                    var nonUserCodeAttr = session.Adaptor.GetType(ctx, "System.Diagnostics.DebuggerNonUserCodeAttribute") as MDB.TypeMirror;
                    external = method.GetCustomAttributes(nonUserCodeAttr, true).Any();
                }
            }

            var location = new DC.SourceLocation(methodName, fileName, frame.LineNumber, frame.ColumnNumber, frame.Location.EndLineNumber, frame.Location.EndColumnNumber, frame.Location.SourceFileHash);

            string addressSpace = string.Empty;
            bool   hasDebugInfo = false;
            string language;

            if (frame.Method != null)
            {
                if (frame.IsNativeTransition)
                {
                    language = "Transition";
                }
                else
                {
                    addressSpace = method.FullName;
                    language     = "Managed";
                    hasDebugInfo = true;
                }
            }
            else
            {
                language = "Native";
            }

            return(new SoftDebuggerStackFrame(frame, addressSpace, location, language, external, hasDebugInfo, hidden, typeFQN, typeFullName));
        }
コード例 #14
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);
        }
コード例 #15
0
 public Subprocess(long threadId, SoftDebuggerSession softDebuggerSession)
 {
     ThreadId = threadId;
     this.softDebuggerSession = softDebuggerSession;
 }
コード例 #16
0
        DC.StackFrame CreateStackFrame(MDB.StackFrame frame)
        {
            MDB.MethodMirror method       = frame.Method;
            MDB.TypeMirror   type         = method.DeclaringType;
            string           fileName     = frame.FileName;
            string           typeFullName = null;
            string           typeFQN      = null;
            string           methodName;

            if (fileName != null)
            {
                fileName = SoftDebuggerSession.NormalizePath(fileName);
            }

            if (method.VirtualMachine.Version.AtLeast(2, 12) && method.IsGenericMethod)
            {
                StringBuilder name = new StringBuilder(method.Name);

                name.Append('<');

                if (method.VirtualMachine.Version.AtLeast(2, 15))
                {
                    bool first = true;

                    foreach (var argumentType in method.GetGenericArguments())
                    {
                        if (!first)
                        {
                            name.Append(", ");
                        }

                        name.Append(session.Adaptor.GetDisplayTypeName(argumentType.FullName));
                        first = false;
                    }
                }

                name.Append('>');

                methodName = name.ToString();
            }
            else
            {
                methodName = method.Name;
            }

            // Compiler generated anonymous/lambda methods
            bool special_method = false;

            if (methodName [0] == '<' && methodName.Contains(">m__"))
            {
                int nidx = methodName.IndexOf(">m__") + 2;
                methodName     = "AnonymousMethod" + methodName.Substring(nidx, method.Name.Length - nidx);
                special_method = true;
            }

            if (type != null)
            {
                string typeDisplayName = session.Adaptor.GetDisplayTypeName(type.FullName);

                if (SoftDebuggerAdaptor.IsGeneratedType(type))
                {
                    // The user-friendly method name is embedded in the generated type name
                    var mn = SoftDebuggerAdaptor.GetNameFromGeneratedType(type);

                    // Strip off the generated type name
                    int dot   = typeDisplayName.LastIndexOf('.');
                    var tname = typeDisplayName.Substring(0, dot);

                    // Keep any type arguments
                    int targs = typeDisplayName.LastIndexOf('<');
                    if (targs > dot + 1)
                    {
                        mn += typeDisplayName.Substring(targs, typeDisplayName.Length - targs);
                    }

                    typeDisplayName = tname;

                    if (special_method)
                    {
                        typeDisplayName += "." + mn;
                    }
                    else
                    {
                        methodName = mn;
                    }
                }

                methodName = typeDisplayName + "." + methodName;

                typeFQN      = type.Module.FullyQualifiedName;
                typeFullName = type.FullName;
            }

            var location = new DC.SourceLocation(methodName, fileName, frame.LineNumber);
            var external = session.IsExternalCode(frame);

            return(new SoftDebuggerStackFrame(frame, method.FullName, location, "Managed", external, true, typeFQN, typeFullName));
        }