Beispiel #1
0
        // 原步骤说明: initialize -> launch -> setBreakpoints -> configurationDone -> 其他后续如获取线程等
        internal void StartDebugger(string method, string methodArgs, string breakpoints)
        {
            if (Interlocked.CompareExchange(ref _runningFlag, 1, 0) != 0)
            {
                throw new Exception("Debugger has started.");
            }

            //1. 构建请求消息,读取类似InvokeController的递交的json格式的调用请求
            //TODO:暂转为utf8再反序列化
            var argsData = Encoding.UTF8.GetBytes(methodArgs);
            var args     = new InvokeArgs();

            var jr = new Utf8JsonReader(argsData);

            if (jr.Deserialize(new ReadedObjects()) is ObjectArray array && array.Count > 0)
            {
                for (int i = 0; i < array.Count; i++)
                {
                    args.Set(i, AnyValue.From(array[i]));
                }
            }
            var req = new InvokeRequire(InvokeSource.Debugger,
                                        InvokeProtocol.Bin /*注意用二进制格式,主进程反序列化*/, IntPtr.Zero, method, args, 0, _hub.Session);

            _breakpoints = JArray.Parse(breakpoints);

            //2.建立调试子进程消息通道并注册调试会话
            _channel = new SharedMemoryChannel(_hub.Session.SessionID.ToString(),
                                               128 /*TODO:*/, DebugSessionManager.MakeMessageDispatcher(), _hub.Session.SessionID);
            _channel.StartReceive();
            _channel.SendMessage(ref req); //直接发送调用调试目标的消息

            DebugSessionManager.Instance.StartSession(this);

            //3.再启动调试进程
            var process = new Process();

            process.StartInfo.FileName = Path.Combine(Runtime.RuntimeContext.Current.AppPath, Server.Consts.LibPath, "netcoredbg");
            //注意netcoredbg通过StartInfo.Arguments覆盖调试目标及参数
#if Windows
            var appContainer = "appbox.AppContainer.exe";
            //process.StartInfo.WorkingDirectory = Path.Combine(Runtime.RuntimeContext.Current.AppPath, Server.Consts.LibPath);
#else
            var appContainer = "appbox.AppContainer";
#endif
            process.StartInfo.Arguments              = $"--interpreter=vscode -- {appContainer} {Runtime.RuntimeContext.PeerId} {_hub.Session.SessionID}";
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.RedirectStandardInput  = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError  = true;
            //process.StartInfo.StandardOutputEncoding = Encoding.UTF8;
            process.ErrorDataReceived += OnError;

            _process = process;
            process.Start();
            Task.Run(async() => await ReadOutputAsync());  //ReadOutputAsync();
            process.BeginErrorReadLine();

            //4.开始发送指令链
            Initialize(InitializeCB);
        }