Example #1
0
		public StackFrame(int i, string nm, Source src, int ln, int col) {
			id = i;
			source = src;
			line = ln;
			column = col;
			name = nm;
		}
		public override Task<DebugResult> StackTrace(int threadReference, int maxLevels)
		{
			CommandLine.WaitForSuspend();
			var stackFrames = new List<StackFrame>();

			ThreadInfo thread = Debugger.ActiveThread;
			if (thread.Id != threadReference) {
				Console.Error.WriteLine("stackTrace: unexpected: active thread should be the one requested");
				thread = FindThread(threadReference);
				if (thread != null) {
					thread.SetActive();
				}
			}

			var bt = thread.Backtrace;
			if (bt != null && bt.FrameCount >= 0) {
				for (var i = 0; i < bt.FrameCount; i++) {

					var frame = bt.GetFrame(i);
					var frameHandle = _frameHandles.Create(frame);

					string name = frame.SourceLocation.MethodName;
					string path = frame.SourceLocation.FileName;
					int line = frame.SourceLocation.Line;
					string sourceName = Path.GetFileName(path);

					var source = new Source(sourceName, ConvertDebuggerPathToClient(path));
					stackFrames.Add(new StackFrame(frameHandle, name, source, ConvertDebuggerLineToClient(line), 0));
				}
			}

			return Task.FromResult(new DebugResult(new StackTraceResponseBody(stackFrames)));
		}
		public override Task<DebugResult> SetBreakpoints(Source source, int[] clientLines)
		{
			if (source.path == null) {
				// we do not support special sources
				return Task.FromResult(new DebugResult(new SetBreakpointsResponseBody()));
			}

			string path = ConvertClientPathToDebugger(source.path);

			if (!HasMonoExtension(path)) {
				// we only support breakpoints in files mono can handle
				return Task.FromResult(new DebugResult(new SetBreakpointsResponseBody()));
			}

			//CommandLine.WaitForSuspend();

			HashSet<int> lin = new HashSet<int>();
			for (int i = 0; i < clientLines.Length; i++) {
				lin.Add(ConvertClientLineToDebugger(clientLines[i]));
			}

			// find all breakpoints for the given path and remember their id and line number
			var bpts = new List<Tuple<int, int>>();
			foreach (var be in Debugger.Breakpoints) {
				var bp = be.Value as Mono.Debugging.Client.Breakpoint;
				if (bp != null && bp.FileName == path) {
					bpts.Add(new Tuple<int,int>((int)be.Key, (int)bp.Line));
				}
			}

			HashSet<int> lin2 = new HashSet<int>();
			foreach (var bpt in bpts) {
				if (lin.Contains(bpt.Item2)) {
					lin2.Add(bpt.Item2);
				}
				else {
					// Console.WriteLine("cleared bpt #{0} for line {1}", bpt.Item1, bpt.Item2);

					BreakEvent b;
					if (Debugger.Breakpoints.TryGetValue(bpt.Item1, out b)) {
						Debugger.Breakpoints.Remove(bpt.Item1);
						Debugger.BreakEvents.Remove(b);
					}
				}
			}

			for (int i = 0; i < clientLines.Length; i++) {
				var l = ConvertClientLineToDebugger(clientLines[i]);
				if (!lin2.Contains(l)) {
					var id = Debugger.GetBreakpointId();
					Debugger.Breakpoints.Add(id, Debugger.BreakEvents.Add(path, l));
					// Console.WriteLine("added bpt #{0} for line {1}", id, l);
				}
			}

			var breakpoints = new List<Breakpoint>();
			foreach (var l in clientLines) {
				breakpoints.Add(new Breakpoint(true, l));
			}
			return Task.FromResult(new DebugResult(new SetBreakpointsResponseBody(breakpoints)));
		}
        public virtual DebugResult Dispatch(string command, dynamic args)
        {
            int thread;

            switch (command) {

            case "initialize":
                return Initialize(args).Result;

            case "launch":
                return Launch(args).Result;

            case "attach":
                return Attach(args).Result;

            case "disconnect":
                return Disconnect().Result;

            case "next":
                thread = GetInt(args, "threadId", 0);
                return Next(thread).Result;

            case "continue":
                thread = GetInt(args, "threadId", 0);
                return Continue(thread).Result;

            case "stepIn":
                thread = GetInt(args, "threadId", 0);
                return StepIn(thread).Result;

            case "stepOut":
                thread = GetInt(args, "threadId", 0);
                return StepOut(thread).Result;

            case "pause":
                thread = GetInt(args, "threadId", 0);
                return Pause(thread).Result;

            case "stackTrace":
                int levels = GetInt(args, "levels", 0);
                thread = GetInt(args, "threadId", 0);
                return StackTrace(thread, levels).Result;

            case "scopes":
                int frameId0 = GetInt(args, "frameId", 0);
                return Scopes(frameId0).Result;

            case "variables":
                int varRef = GetInt(args, "variablesReference", -1);
                if (varRef == -1) {
                    return new DebugResult(1009, "variables: property 'variablesReference' is missing");
                }
                return Variables(varRef).Result;

            case "source":
                int sourceRef = GetInt(args, "sourceReference", -1);
                if (sourceRef == -1) {
                    return new DebugResult(1010, "source: property 'sourceReference' is missing");
                }
                return Source(sourceRef).Result;

            case "threads":
                return Threads().Result;

            case "setBreakpoints":
                string path = null;
                string name = null;
                int reference = 0;
                int noOfSources = 0;

                dynamic source = args.source;
                if (source != null) {
                    string p = (string)source.path;
                    if (p != null && p.Trim().Length > 0) {
                        path = p;
                        noOfSources++;
                    }
                    try {
                        reference = (int)source.reference;
                        if (reference > 0) {
                            noOfSources++;
                        }
                    }
                    catch (RuntimeBinderException) {
                        reference = 0;
                    }
                    string nm = (string)source.name;
                    if (nm != null && nm.Trim().Length > 0) {
                        name = nm;
                        noOfSources++;
                    }
                }
                if (noOfSources == 1) {
                    var src2 = new Source(name, path, reference);
                    var lines = args.lines.ToObject<int[]>();
                    return SetBreakpoints(src2, lines).Result;
                }
                if (noOfSources > 1) {
                    return new DebugResult(1011, "setBreakpoints: only one of 'name', 'path', or 'reference' may be specified in a 'source' object");
                }
                return new DebugResult(1012, "setBreakpoints: property 'source' is empty or misformed");

            case "setExceptionBreakpoints":
                string[] filters = null;
                if (args.filters != null) {
                    filters = args.filters.ToObject<string[]>();
                }
                else {
                    filters = new string[0];
                }
                return SetExceptionBreakpoints(filters).Result;

            case "evaluate":
                int frameId = GetInt(args, "frameId", -1);
                var expression = GetString(args, "expression");
                if (expression == null) {
                    return new DebugResult(1013, "evaluate: property 'expression' is missing, null, or empty");
                }
                return Evaluate(frameId, expression).Result;

            default:
                return new DebugResult(1014, "unrecognized request: {_request}", new { _request = command });
            }
        }
 public abstract Task<DebugResult> SetBreakpoints(Source source, int[] lines);