From 8cb5f7a1111d9f1945cd1073030c13e9a0f423a0 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Thu, 18 May 2017 17:41:17 +0300 Subject: [PATCH 01/14] Added xamarin connection provider --- mono-debug.csproj | 2 ++ src/DebugSession.cs | 6 ++++++ src/MonoDebugSession.cs | 30 ++++++++++++++++++++++++++ src/XamarinConnectionProvider.cs | 37 ++++++++++++++++++++++++++++++++ src/XamarinDebuggerArgs.cs | 14 ++++++++++++ 5 files changed, 89 insertions(+) create mode 100644 src/XamarinConnectionProvider.cs create mode 100644 src/XamarinDebuggerArgs.cs diff --git a/mono-debug.csproj b/mono-debug.csproj index 51393e2..948c098 100644 --- a/mono-debug.csproj +++ b/mono-debug.csproj @@ -66,6 +66,8 @@ + + diff --git a/src/DebugSession.cs b/src/DebugSession.cs index e2b3fd5..0678058 100644 --- a/src/DebugSession.cs +++ b/src/DebugSession.cs @@ -346,6 +346,10 @@ protected override void DispatchRequest(string command, dynamic args, Response r Attach(response, args); break; + case "runXA": + RunXamarinAndroid(response, args); + break; + case "disconnect": Disconnect(response, args); break; @@ -426,6 +430,8 @@ protected override void DispatchRequest(string command, dynamic args, Response r public abstract void Attach(Response response, dynamic arguments); + public abstract void RunXamarinAndroid(Response response, dynamic arguments); + public abstract void Disconnect(Response response, dynamic arguments); public virtual void SetFunctionBreakpoints(Response response, dynamic arguments) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index 72c94f9..487630a 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -415,6 +415,36 @@ public override void Attach(Response response, dynamic args) SendResponse(response); } + public override void RunXamarinAndroid(Response response, dynamic args) + { + _attachMode = true; + + SetExceptionBreakpoints(args.__exceptionOptions); + + // validate argument 'port' + var packageName = getInt(args, "packageName", -1); + if (packageName == -1) { + SendErrorResponse(response, 3008, "Property 'packageName' is missing."); + return; + } + + lock (_lock) { + + _debuggeeKilled = false; + + var args0 = new XamarinDebuggerArgs(10000) { + MaxConnectionAttempts = MAX_CONNECTION_ATTEMPTS, + TimeBetweenConnectionAttempts = CONNECTION_ATTEMPT_INTERVAL + }; + + _session.Run(new Mono.Debugging.Soft.SoftDebuggerStartInfo(args0), _debuggerSessionOptions); + + _debuggeeExecuting = true; + } + + SendResponse(response); + } + public override void Disconnect(Response response, dynamic args) { if (_attachMode) { diff --git a/src/XamarinConnectionProvider.cs b/src/XamarinConnectionProvider.cs new file mode 100644 index 0000000..1f360fe --- /dev/null +++ b/src/XamarinConnectionProvider.cs @@ -0,0 +1,37 @@ +using System; +using Mono.Debugger.Soft; +using Mono.Debugging.Client; +using Mono.Debugging.Soft; + +namespace VSCodeDebug +{ + public class XamarinConnectionProvider : ISoftDebuggerConnectionProvider + { + private readonly int _port; + + public XamarinConnectionProvider(int port) + { + _port = port; + } + + public IAsyncResult BeginConnect(DebuggerStartInfo dsi, AsyncCallback callback) + { + throw new NotImplementedException(); + } + + public void CancelConnect(IAsyncResult result) + { + throw new NotImplementedException(); + } + + public void EndConnect(IAsyncResult result, out VirtualMachine vm, out string appName) + { + throw new NotImplementedException(); + } + + public bool ShouldRetryConnection(Exception ex) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/src/XamarinDebuggerArgs.cs b/src/XamarinDebuggerArgs.cs new file mode 100644 index 0000000..4d3483b --- /dev/null +++ b/src/XamarinDebuggerArgs.cs @@ -0,0 +1,14 @@ +using Mono.Debugging.Soft; + +namespace VSCodeDebug +{ + public class XamarinDebuggerArgs : SoftDebuggerStartArgs + { + public override ISoftDebuggerConnectionProvider ConnectionProvider { get; } + + public XamarinDebuggerArgs(int port) + { + ConnectionProvider = new XamarinConnectionProvider(port); + } + } +} \ No newline at end of file From 7d846321f37882e7289a0c3426796b8f52a733ab Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Mon, 29 May 2017 16:56:11 +0300 Subject: [PATCH 02/14] added xamarin.anroid launch --- package.json | 6 +++++- package.nls.json | 1 + src/DebugSession.cs | 28 ++++++++++--------------- src/MonoDebugSession.cs | 45 ++++++++++++++++++++++++++++++++++------- 4 files changed, 55 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 80acada..25dc8f5 100644 --- a/package.json +++ b/package.json @@ -144,12 +144,16 @@ ], "configurationAttributes": { "launch": { - "required": ["program"], + "required": [], "properties": { "program": { "type": "string", "description": "%mono.launch.program.description%" }, + "packageName":{ + "type": "string", + "description": "%mono.launch.packageName.description%" + }, "args": { "type": "array", "description": "%mono.launch.args.description%", diff --git a/package.nls.json b/package.nls.json index 71436cd..901916f 100644 --- a/package.nls.json +++ b/package.nls.json @@ -17,6 +17,7 @@ "mono.attach.config.name": "Attach", "mono.launch.program.description": "Absolute path to the program.", + "mono.launch.packageName.description": "Android package name.", "mono.launch.args.description": "Command line arguments passed to the program.", "mono.launch.cwd.description": "Absolute path to the working directory of the program being debugged.", "mono.launch.runtimeExecutable.description": "Absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.", diff --git a/src/DebugSession.cs b/src/DebugSession.cs index 0678058..45c8a95 100644 --- a/src/DebugSession.cs +++ b/src/DebugSession.cs @@ -35,8 +35,8 @@ public class StackFrame public int line { get; } public int column { get; } public string name { get; } - public string presentationHint { get; } - + public string presentationHint { get; } + public StackFrame(int id, string name, Source source, int line, int column) { this.id = id; this.name = name; @@ -50,7 +50,7 @@ public StackFrame(int id, string name, Source source, int line, int column) { if (this.line==0 || this.source==null || string.IsNullOrEmpty(this.source.name) || string.IsNullOrEmpty(this.source.path)) { this.presentationHint = "label"; this.source = null; - } else { + } else { this.presentationHint = "normal"; } } @@ -116,14 +116,14 @@ private Source(string path, int sourceReference = 0) { this.name = Path.GetFileName(path); this.path = path; this.sourceReference = sourceReference; - } - - public static Source Create(string name, string path, int sourceReference = 0) { - if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(path)) - return null; - - return new Source(name, path, sourceReference); - } + } + + public static Source Create(string name, string path, int sourceReference = 0) { + if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(path)) + return null; + + return new Source(name, path, sourceReference); + } } public class Breakpoint @@ -346,10 +346,6 @@ protected override void DispatchRequest(string command, dynamic args, Response r Attach(response, args); break; - case "runXA": - RunXamarinAndroid(response, args); - break; - case "disconnect": Disconnect(response, args); break; @@ -430,8 +426,6 @@ protected override void DispatchRequest(string command, dynamic args, Response r public abstract void Attach(Response response, dynamic arguments); - public abstract void RunXamarinAndroid(Response response, dynamic arguments); - public abstract void Disconnect(Response response, dynamic arguments); public virtual void SetFunctionBreakpoints(Response response, dynamic arguments) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index 487630a..4fa82e2 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -9,7 +9,7 @@ using System.Linq; using System.Net; using Mono.Debugging.Client; - +using System.Diagnostics; namespace VSCodeDebug { @@ -180,7 +180,19 @@ public override void Initialize(Response response, dynamic args) SendEvent(new InitializedEvent()); } - public override async void Launch(Response response, dynamic args) + public override void Launch(Response response, dynamic args) + { + if (args.packageName != null) + { + LaunchXamarinAndroid(response, args); + } + else + { + LaunchMono(response, args); + } + } + + public async void LaunchMono(Response response, dynamic args) { _attachMode = false; @@ -415,24 +427,28 @@ public override void Attach(Response response, dynamic args) SendResponse(response); } - public override void RunXamarinAndroid(Response response, dynamic args) + public void LaunchXamarinAndroid(Response response, dynamic args) { _attachMode = true; SetExceptionBreakpoints(args.__exceptionOptions); - // validate argument 'port' - var packageName = getInt(args, "packageName", -1); - if (packageName == -1) { + var packageName = getString(args, "packageName", null); + if (packageName == null) { SendErrorResponse(response, 3008, "Property 'packageName' is missing."); return; } + var forwardOutput = RunAdb("forward tcp:0 tcp:10000"); + var port = int.Parse(forwardOutput); + RunAdb("shell setprop port=10000,timeout=2000000000"); + RunAdb($"shell monkey -p {packageName} -c android.intent.category.LAUNCHER 1"); + lock (_lock) { _debuggeeKilled = false; - var args0 = new XamarinDebuggerArgs(10000) { + var args0 = new XamarinDebuggerArgs(port) { MaxConnectionAttempts = MAX_CONNECTION_ATTEMPTS, TimeBetweenConnectionAttempts = CONNECTION_ATTEMPT_INTERVAL }; @@ -445,6 +461,21 @@ public override void RunXamarinAndroid(Response response, dynamic args) SendResponse(response); } + private string RunAdb(string args) + { + var adbProcessInfo = new ProcessStartInfo + { + FileName = "adb", + Arguments = args, + RedirectStandardOutput = true, + UseShellExecute = false + }; + var adbProcess = Process.Start(adbProcessInfo); + var result = adbProcess.StandardOutput.ReadToEnd(); + adbProcess.WaitForExit(); + return result; + } + public override void Disconnect(Response response, dynamic args) { if (_attachMode) { From e2ebaea16e1245989dadd8445de80bdf5e702c31 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Mon, 29 May 2017 22:26:04 +0300 Subject: [PATCH 03/14] added xamarin connection provider --- mono-debug.csproj | 2 + src/XamarinConnectionProvider.cs | 13 +++-- src/XamarinTcpConnection.cs | 46 +++++++++++++++ src/XamarinVirtualMachineManager.cs | 88 +++++++++++++++++++++++++++++ 4 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 src/XamarinTcpConnection.cs create mode 100644 src/XamarinVirtualMachineManager.cs diff --git a/mono-debug.csproj b/mono-debug.csproj index 948c098..7e22a94 100644 --- a/mono-debug.csproj +++ b/mono-debug.csproj @@ -68,6 +68,8 @@ + + diff --git a/src/XamarinConnectionProvider.cs b/src/XamarinConnectionProvider.cs index 1f360fe..f4dae9b 100644 --- a/src/XamarinConnectionProvider.cs +++ b/src/XamarinConnectionProvider.cs @@ -1,8 +1,12 @@ using System; +using System.IO; +using System.Net; +using System.Net.Sockets; using Mono.Debugger.Soft; using Mono.Debugging.Client; using Mono.Debugging.Soft; + namespace VSCodeDebug { public class XamarinConnectionProvider : ISoftDebuggerConnectionProvider @@ -16,22 +20,23 @@ public XamarinConnectionProvider(int port) public IAsyncResult BeginConnect(DebuggerStartInfo dsi, AsyncCallback callback) { - throw new NotImplementedException(); + return XamarinVirtualMachineManager.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _port), null, callback); } public void CancelConnect(IAsyncResult result) { - throw new NotImplementedException(); + XamarinVirtualMachineManager.CancelConnection(result); } public void EndConnect(IAsyncResult result, out VirtualMachine vm, out string appName) { - throw new NotImplementedException(); + vm = XamarinVirtualMachineManager.EndConnect(result); + appName = null; } public bool ShouldRetryConnection(Exception ex) { - throw new NotImplementedException(); + return false; } } } \ No newline at end of file diff --git a/src/XamarinTcpConnection.cs b/src/XamarinTcpConnection.cs new file mode 100644 index 0000000..288884c --- /dev/null +++ b/src/XamarinTcpConnection.cs @@ -0,0 +1,46 @@ +using System.IO; +using System.Net; +using System.Net.Sockets; +using Mono.Debugger.Soft; + +namespace VSCodeDebug +{ + class XamarinTcpConnection : Connection + { + Socket socket; + + internal XamarinTcpConnection (Socket socket, TextWriter logWriter) + : base (logWriter) + { + this.socket = socket; + //socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.NoDelay, 1); + } + + internal EndPoint EndPoint { + get { + return socket.RemoteEndPoint; + } + } + + protected override int TransportSend (byte[] buf, int buf_offset, int len) + { + return socket.Send (buf, buf_offset, len, SocketFlags.None); + } + + protected override int TransportReceive (byte[] buf, int buf_offset, int len) + { + return socket.Receive (buf, buf_offset, len, SocketFlags.None); + } + + protected override void TransportSetTimeouts (int send_timeout, int receive_timeout) + { + socket.SendTimeout = send_timeout; + socket.ReceiveTimeout = receive_timeout; + } + + protected override void TransportClose () + { + socket.Close (); + } + } +} \ No newline at end of file diff --git a/src/XamarinVirtualMachineManager.cs b/src/XamarinVirtualMachineManager.cs new file mode 100644 index 0000000..43b2bf8 --- /dev/null +++ b/src/XamarinVirtualMachineManager.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Runtime.Remoting.Messaging; +using System.Text; +using Mono.Debugger.Soft; + +namespace VSCodeDebug +{ + + public static class XamarinVirtualMachineManager + { + private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket, TextWriter logWriter); + private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock, TextWriter logWriter); + private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); + + public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { + if (con_sock != null) { + try { + con_sock.Connect (con_ep); + } catch (Exception) { + try { + dbg_sock.Close (); + } catch { } + throw; + } + } + + try { + dbg_sock.Connect (dbg_ep); + byte[] byData = new byte[] { 19 } ; + dbg_sock.Send(byData, 0, byData.Length, SocketFlags.None); + byData = System.Text.Encoding.ASCII.GetBytes("start debugger: sdb"); + dbg_sock.Send(byData, 0, byData.Length, SocketFlags.None); + } catch (Exception) { + if (con_sock != null) { + try { + con_sock.Close (); + } catch { } + } + throw; + } + + Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); + StreamReader console = con_sock != null ? new StreamReader (new NetworkStream (con_sock)) : null; + + return VirtualMachineManager.Connect (transport, console, null); + } + + public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, AsyncCallback callback, TextWriter logWriter = null) { + return BeginConnect (dbg_ep, null, callback, logWriter); + } + + public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback, TextWriter logWriter = null) { + Socket dbg_sock = null; + Socket con_sock = null; + + dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + if (con_ep != null) { + con_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + } + + ConnectCallback c = new ConnectCallback (ConnectInternal); + return c.BeginInvoke (dbg_sock, con_sock, dbg_ep, con_ep, logWriter, callback, con_sock ?? dbg_sock); + } + + public static VirtualMachine EndConnect (IAsyncResult asyncResult) { + if (asyncResult == null) + throw new ArgumentNullException ("asyncResult"); + + if (!asyncResult.IsCompleted) + asyncResult.AsyncWaitHandle.WaitOne (); + + AsyncResult result = (AsyncResult) asyncResult; + ConnectCallback cb = (ConnectCallback) result.AsyncDelegate; + return cb.EndInvoke (asyncResult); + } + + public static void CancelConnection (IAsyncResult asyncResult) + { + ((Socket)asyncResult.AsyncState).Close (); + } + } +} From 7559cdb3a1e70c53ea697dcce32a7aabc3aa2e52 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Tue, 30 May 2017 21:34:08 +0300 Subject: [PATCH 04/14] close old application before start new --- src/MonoDebugSession.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index 4fa82e2..a9aa866 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -442,6 +442,7 @@ public void LaunchXamarinAndroid(Response response, dynamic args) var forwardOutput = RunAdb("forward tcp:0 tcp:10000"); var port = int.Parse(forwardOutput); RunAdb("shell setprop port=10000,timeout=2000000000"); + RunAdb($"shell am force-stop {packageName}"); RunAdb($"shell monkey -p {packageName} -c android.intent.category.LAUNCHER 1"); lock (_lock) { From d1c1aa05cbdda1f44c5f5f0c0baa723d998d6a7a Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Tue, 30 May 2017 21:41:40 +0300 Subject: [PATCH 05/14] fixed set prop --- src/MonoDebugSession.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index a9aa866..ed6ddde 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -441,7 +441,7 @@ public void LaunchXamarinAndroid(Response response, dynamic args) var forwardOutput = RunAdb("forward tcp:0 tcp:10000"); var port = int.Parse(forwardOutput); - RunAdb("shell setprop port=10000,timeout=2000000000"); + RunAdb("shell setprop debug.mono.connect port=10000,timeout=2000000000"); RunAdb($"shell am force-stop {packageName}"); RunAdb($"shell monkey -p {packageName} -c android.intent.category.LAUNCHER 1"); From a014d0ba81408cdeabae4808af2c0197b51ea8e2 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Tue, 30 May 2017 22:41:44 +0300 Subject: [PATCH 06/14] added small sleep --- src/MonoDebugSession.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index ed6ddde..4ab18cd 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -444,6 +444,7 @@ public void LaunchXamarinAndroid(Response response, dynamic args) RunAdb("shell setprop debug.mono.connect port=10000,timeout=2000000000"); RunAdb($"shell am force-stop {packageName}"); RunAdb($"shell monkey -p {packageName} -c android.intent.category.LAUNCHER 1"); + System.Threading.Thread.Sleep(500); lock (_lock) { From 2c7e0173f7e5207edeaf4b072217b3ebc56d63c1 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Wed, 31 May 2017 14:19:39 +0300 Subject: [PATCH 07/14] undo redundant changes in debugsession --- src/DebugSession.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/DebugSession.cs b/src/DebugSession.cs index 45c8a95..e2b3fd5 100644 --- a/src/DebugSession.cs +++ b/src/DebugSession.cs @@ -35,8 +35,8 @@ public class StackFrame public int line { get; } public int column { get; } public string name { get; } - public string presentationHint { get; } - + public string presentationHint { get; } + public StackFrame(int id, string name, Source source, int line, int column) { this.id = id; this.name = name; @@ -50,7 +50,7 @@ public StackFrame(int id, string name, Source source, int line, int column) { if (this.line==0 || this.source==null || string.IsNullOrEmpty(this.source.name) || string.IsNullOrEmpty(this.source.path)) { this.presentationHint = "label"; this.source = null; - } else { + } else { this.presentationHint = "normal"; } } @@ -116,14 +116,14 @@ private Source(string path, int sourceReference = 0) { this.name = Path.GetFileName(path); this.path = path; this.sourceReference = sourceReference; - } - - public static Source Create(string name, string path, int sourceReference = 0) { - if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(path)) - return null; - - return new Source(name, path, sourceReference); - } + } + + public static Source Create(string name, string path, int sourceReference = 0) { + if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(path)) + return null; + + return new Source(name, path, sourceReference); + } } public class Breakpoint From 05f09dafa46eda53df5097577f875588a3fdc07c Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Mon, 19 Jun 2017 18:26:44 +0300 Subject: [PATCH 08/14] trying to connect device output --- src/XamarinConnectionProvider.cs | 3 +- src/XamarinVirtualMachineManager.cs | 184 +++++++++++++++------------- 2 files changed, 98 insertions(+), 89 deletions(-) diff --git a/src/XamarinConnectionProvider.cs b/src/XamarinConnectionProvider.cs index f4dae9b..7a5553c 100644 --- a/src/XamarinConnectionProvider.cs +++ b/src/XamarinConnectionProvider.cs @@ -20,7 +20,8 @@ public XamarinConnectionProvider(int port) public IAsyncResult BeginConnect(DebuggerStartInfo dsi, AsyncCallback callback) { - return XamarinVirtualMachineManager.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), _port), null, callback); + var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), _port); + return XamarinVirtualMachineManager.BeginConnect(endPoint, endPoint, callback); } public void CancelConnect(IAsyncResult result) diff --git a/src/XamarinVirtualMachineManager.cs b/src/XamarinVirtualMachineManager.cs index 43b2bf8..9d1fb08 100644 --- a/src/XamarinVirtualMachineManager.cs +++ b/src/XamarinVirtualMachineManager.cs @@ -1,88 +1,96 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Net; -using System.Net.Sockets; -using System.Runtime.Remoting.Messaging; -using System.Text; -using Mono.Debugger.Soft; - -namespace VSCodeDebug -{ - - public static class XamarinVirtualMachineManager - { - private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket, TextWriter logWriter); - private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock, TextWriter logWriter); - private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); - - public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { - if (con_sock != null) { - try { - con_sock.Connect (con_ep); - } catch (Exception) { - try { - dbg_sock.Close (); - } catch { } - throw; - } - } - - try { - dbg_sock.Connect (dbg_ep); - byte[] byData = new byte[] { 19 } ; - dbg_sock.Send(byData, 0, byData.Length, SocketFlags.None); - byData = System.Text.Encoding.ASCII.GetBytes("start debugger: sdb"); - dbg_sock.Send(byData, 0, byData.Length, SocketFlags.None); - } catch (Exception) { - if (con_sock != null) { - try { - con_sock.Close (); - } catch { } - } - throw; - } - - Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); - StreamReader console = con_sock != null ? new StreamReader (new NetworkStream (con_sock)) : null; - - return VirtualMachineManager.Connect (transport, console, null); - } - - public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, AsyncCallback callback, TextWriter logWriter = null) { - return BeginConnect (dbg_ep, null, callback, logWriter); - } - - public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback, TextWriter logWriter = null) { - Socket dbg_sock = null; - Socket con_sock = null; - - dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - if (con_ep != null) { - con_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - } - - ConnectCallback c = new ConnectCallback (ConnectInternal); - return c.BeginInvoke (dbg_sock, con_sock, dbg_ep, con_ep, logWriter, callback, con_sock ?? dbg_sock); - } - - public static VirtualMachine EndConnect (IAsyncResult asyncResult) { - if (asyncResult == null) - throw new ArgumentNullException ("asyncResult"); - - if (!asyncResult.IsCompleted) - asyncResult.AsyncWaitHandle.WaitOne (); - - AsyncResult result = (AsyncResult) asyncResult; - ConnectCallback cb = (ConnectCallback) result.AsyncDelegate; - return cb.EndInvoke (asyncResult); - } - - public static void CancelConnection (IAsyncResult asyncResult) - { - ((Socket)asyncResult.AsyncState).Close (); - } - } -} +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Runtime.Remoting.Messaging; +using System.Text; +using Mono.Debugger.Soft; + +namespace VSCodeDebug +{ + + public static class XamarinVirtualMachineManager + { + private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket, TextWriter logWriter); + private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock, TextWriter logWriter); + private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); + + public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { + if (con_sock != null) { + try + { + con_sock.Connect(con_ep); + SendCommand(con_sock, "connect stdout"); + } + catch (Exception) { + try { + dbg_sock.Close (); + } catch { } + throw; + } + } + + try { + dbg_sock.Connect (dbg_ep); + SendCommand(dbg_sock, "start debugger: sdb"); + } catch (Exception) { + if (con_sock != null) { + try { + con_sock.Close (); + } catch { } + } + throw; + } + + Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); + StreamReader console = con_sock != null ? new StreamReader (new NetworkStream (con_sock)) : null; + + return VirtualMachineManager.Connect (transport, console, null); + } + + private static void SendCommand(Socket socket, string command) + { + byte[] commandBin = System.Text.Encoding.ASCII.GetBytes(command); + byte[] commandLenght = new byte[] { (byte)commandBin.Length }; + socket.Send(commandLenght, 0, commandLenght.Length, SocketFlags.None); + socket.Send(commandBin, 0, commandBin.Length, SocketFlags.None); + } + + public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, AsyncCallback callback, TextWriter logWriter = null) { + return BeginConnect (dbg_ep, null, callback, logWriter); + } + + public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback, TextWriter logWriter = null) { + Socket dbg_sock = null; + Socket con_sock = null; + + dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + if (con_ep != null) { + con_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + } + + ConnectCallback c = new ConnectCallback (ConnectInternal); + return c.BeginInvoke (dbg_sock, con_sock, dbg_ep, con_ep, logWriter, callback, con_sock ?? dbg_sock); + } + + public static VirtualMachine EndConnect (IAsyncResult asyncResult) { + if (asyncResult == null) + throw new ArgumentNullException ("asyncResult"); + + if (!asyncResult.IsCompleted) + asyncResult.AsyncWaitHandle.WaitOne (); + + AsyncResult result = (AsyncResult) asyncResult; + ConnectCallback cb = (ConnectCallback) result.AsyncDelegate; + return cb.EndInvoke (asyncResult); + } + + public static void CancelConnection (IAsyncResult asyncResult) + { + ((Socket)asyncResult.AsyncState).Close (); + } + } +} From 3693fe6918c9448f9678a9f4e62f71365ab4d513 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Mon, 7 Aug 2017 19:12:20 +0300 Subject: [PATCH 09/14] try to use --- src/MonoDebugSession.cs | 30 ++++++++++++++++++++++++----- src/XamarinConnectionProvider.cs | 15 +++++++++++++-- src/XamarinDebuggerArgs.cs | 27 +++++++++++++------------- src/XamarinVirtualMachineManager.cs | 21 ++++++++++++++++++-- 4 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index 4ab18cd..573275d 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -439,11 +439,12 @@ public void LaunchXamarinAndroid(Response response, dynamic args) return; } - var forwardOutput = RunAdb("forward tcp:0 tcp:10000"); + //var deviceConsole = RunAdb("shell logcat"); + var forwardOutput = RunAdbForResult("forward tcp:0 tcp:10000"); var port = int.Parse(forwardOutput); - RunAdb("shell setprop debug.mono.connect port=10000,timeout=2000000000"); - RunAdb($"shell am force-stop {packageName}"); - RunAdb($"shell monkey -p {packageName} -c android.intent.category.LAUNCHER 1"); + RunAdbForResult("shell setprop debug.mono.connect port=10000,timeout=2000000000"); + RunAdbForResult($"shell am force-stop {packageName}"); + RunAdbForResult($"shell monkey -p {packageName} -c android.intent.category.LAUNCHER 1"); System.Threading.Thread.Sleep(500); lock (_lock) { @@ -463,7 +464,7 @@ public void LaunchXamarinAndroid(Response response, dynamic args) SendResponse(response); } - private string RunAdb(string args) + private string RunAdbForResult(string args) { var adbProcessInfo = new ProcessStartInfo { @@ -478,6 +479,25 @@ private string RunAdb(string args) return result; } + private StreamReader RunAdb(string args) + { + var adbProcessInfo = new ProcessStartInfo + { + FileName = "adb", + Arguments = args, + RedirectStandardOutput = true, + UseShellExecute = false + }; + var adbProcess = Process.Start(adbProcessInfo); + adbProcess.ErrorDataReceived += (o, e) => { + Console.WriteLine(e.Data); + }; + adbProcess.OutputDataReceived += (o, e) => { + Console.WriteLine(e.Data); + }; + return adbProcess.StandardOutput; + } + public override void Disconnect(Response response, dynamic args) { if (_attachMode) { diff --git a/src/XamarinConnectionProvider.cs b/src/XamarinConnectionProvider.cs index 7a5553c..f6aa1e6 100644 --- a/src/XamarinConnectionProvider.cs +++ b/src/XamarinConnectionProvider.cs @@ -12,16 +12,27 @@ namespace VSCodeDebug public class XamarinConnectionProvider : ISoftDebuggerConnectionProvider { private readonly int _port; + private readonly StreamReader _console; - public XamarinConnectionProvider(int port) + public XamarinConnectionProvider(int port, StreamReader console = null) { _port = port; + _console = console; } public IAsyncResult BeginConnect(DebuggerStartInfo dsi, AsyncCallback callback) { + IAsyncResult result; var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), _port); - return XamarinVirtualMachineManager.BeginConnect(endPoint, endPoint, callback); + if (_console != null) + { + result = XamarinVirtualMachineManager.BeginConnect(endPoint, _console, callback); + } + else + { + result = XamarinVirtualMachineManager.BeginConnect(endPoint, endPoint, callback); + } + return result; } public void CancelConnect(IAsyncResult result) diff --git a/src/XamarinDebuggerArgs.cs b/src/XamarinDebuggerArgs.cs index 4d3483b..db6cfb8 100644 --- a/src/XamarinDebuggerArgs.cs +++ b/src/XamarinDebuggerArgs.cs @@ -1,14 +1,15 @@ -using Mono.Debugging.Soft; - -namespace VSCodeDebug -{ - public class XamarinDebuggerArgs : SoftDebuggerStartArgs - { - public override ISoftDebuggerConnectionProvider ConnectionProvider { get; } - - public XamarinDebuggerArgs(int port) - { - ConnectionProvider = new XamarinConnectionProvider(port); - } - } +using Mono.Debugging.Soft; +using System.IO; + +namespace VSCodeDebug +{ + public class XamarinDebuggerArgs : SoftDebuggerStartArgs + { + public override ISoftDebuggerConnectionProvider ConnectionProvider { get; } + + public XamarinDebuggerArgs(int port, StreamReader deviceConsole = null) + { + ConnectionProvider = new XamarinConnectionProvider(port, deviceConsole); + } + } } \ No newline at end of file diff --git a/src/XamarinVirtualMachineManager.cs b/src/XamarinVirtualMachineManager.cs index 9d1fb08..67fb70a 100644 --- a/src/XamarinVirtualMachineManager.cs +++ b/src/XamarinVirtualMachineManager.cs @@ -16,13 +16,14 @@ public static class XamarinVirtualMachineManager private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket, TextWriter logWriter); private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock, TextWriter logWriter); private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); + private delegate VirtualMachine ConnectCallbackWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter); public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { if (con_sock != null) { try { con_sock.Connect(con_ep); - SendCommand(con_sock, "connect stdout"); + SendCommand(con_sock, "ping"); } catch (Exception) { try { @@ -50,6 +51,14 @@ public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, return VirtualMachineManager.Connect (transport, console, null); } + public static VirtualMachine ConnectInternalWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) + { + dbg_sock.Connect (dbg_ep); + SendCommand(dbg_sock, "start debugger: sdb"); + Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); + return VirtualMachineManager.Connect (transport, console, null); + } + private static void SendCommand(Socket socket, string command) { byte[] commandBin = System.Text.Encoding.ASCII.GetBytes(command); @@ -59,7 +68,7 @@ private static void SendCommand(Socket socket, string command) } public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, AsyncCallback callback, TextWriter logWriter = null) { - return BeginConnect (dbg_ep, null, callback, logWriter); + return BeginConnect (dbg_ep, (IPEndPoint)null, callback, logWriter); } public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback, TextWriter logWriter = null) { @@ -76,6 +85,14 @@ public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, A return c.BeginInvoke (dbg_sock, con_sock, dbg_ep, con_ep, logWriter, callback, con_sock ?? dbg_sock); } + public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, StreamReader console, AsyncCallback callback, TextWriter logWriter = null) { + Socket dbg_sock = null; + dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + + var c = new ConnectCallbackWithCustomConsole (ConnectInternalWithCustomConsole); + return c.BeginInvoke (dbg_sock, dbg_ep, console, logWriter, callback, logWriter); + } + public static VirtualMachine EndConnect (IAsyncResult asyncResult) { if (asyncResult == null) throw new ArgumentNullException ("asyncResult"); From 02769cca536202be6d851b72196474664cdca42b Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Thu, 31 Aug 2017 10:23:11 +0300 Subject: [PATCH 10/14] fixed logcat shell command --- src/MonoDebugSession.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index 573275d..29d9caf 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -439,7 +439,6 @@ public void LaunchXamarinAndroid(Response response, dynamic args) return; } - //var deviceConsole = RunAdb("shell logcat"); var forwardOutput = RunAdbForResult("forward tcp:0 tcp:10000"); var port = int.Parse(forwardOutput); RunAdbForResult("shell setprop debug.mono.connect port=10000,timeout=2000000000"); @@ -450,8 +449,8 @@ public void LaunchXamarinAndroid(Response response, dynamic args) lock (_lock) { _debuggeeKilled = false; - - var args0 = new XamarinDebuggerArgs(port) { + var console = RunAdb("shell mono-stdout:D *:S"); + var args0 = new XamarinDebuggerArgs(port, console) { MaxConnectionAttempts = MAX_CONNECTION_ATTEMPTS, TimeBetweenConnectionAttempts = CONNECTION_ATTEMPT_INTERVAL }; From 43baddd72be4dfef9a9d4496800e930ba02f8039 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Thu, 31 Aug 2017 10:23:45 +0300 Subject: [PATCH 11/14] code cleanup + bugfix --- src/XamarinVirtualMachineManager.cs | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/XamarinVirtualMachineManager.cs b/src/XamarinVirtualMachineManager.cs index 67fb70a..97e1d06 100644 --- a/src/XamarinVirtualMachineManager.cs +++ b/src/XamarinVirtualMachineManager.cs @@ -13,17 +13,20 @@ namespace VSCodeDebug public static class XamarinVirtualMachineManager { + private const string START_DEBUGGER_COMMAND = "start debugger: sdb"; + private const string CONNECT_STDOUT_COMMAND = "connect stdout"; + private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket, TextWriter logWriter); private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock, TextWriter logWriter); private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); private delegate VirtualMachine ConnectCallbackWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter); - public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { + private static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { if (con_sock != null) { try { con_sock.Connect(con_ep); - SendCommand(con_sock, "ping"); + SendCommand(con_sock, CONNECT_STDOUT_COMMAND); } catch (Exception) { try { @@ -35,7 +38,7 @@ public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, try { dbg_sock.Connect (dbg_ep); - SendCommand(dbg_sock, "start debugger: sdb"); + SendCommand(dbg_sock, START_DEBUGGER_COMMAND); } catch (Exception) { if (con_sock != null) { try { @@ -51,10 +54,10 @@ public static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, return VirtualMachineManager.Connect (transport, console, null); } - public static VirtualMachine ConnectInternalWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) + private static VirtualMachine ConnectInternalWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) { dbg_sock.Connect (dbg_ep); - SendCommand(dbg_sock, "start debugger: sdb"); + SendCommand(dbg_sock, START_DEBUGGER_COMMAND); Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); return VirtualMachineManager.Connect (transport, console, null); } @@ -67,10 +70,6 @@ private static void SendCommand(Socket socket, string command) socket.Send(commandBin, 0, commandBin.Length, SocketFlags.None); } - public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, AsyncCallback callback, TextWriter logWriter = null) { - return BeginConnect (dbg_ep, (IPEndPoint)null, callback, logWriter); - } - public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback, TextWriter logWriter = null) { Socket dbg_sock = null; Socket con_sock = null; @@ -89,8 +88,8 @@ public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, StreamReader console Socket dbg_sock = null; dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - var c = new ConnectCallbackWithCustomConsole (ConnectInternalWithCustomConsole); - return c.BeginInvoke (dbg_sock, dbg_ep, console, logWriter, callback, logWriter); + ConnectCallbackWithCustomConsole c = new ConnectCallbackWithCustomConsole (ConnectInternalWithCustomConsole); + return c.BeginInvoke (dbg_sock, dbg_ep, console, logWriter, callback, dbg_sock); } public static VirtualMachine EndConnect (IAsyncResult asyncResult) { From 472c07b9a9362fe3ba68c0c9e4c6706e38e6d835 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Thu, 31 Aug 2017 12:47:26 +0300 Subject: [PATCH 12/14] code cleanup --- src/XamarinVirtualMachineManager.cs | 43 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/XamarinVirtualMachineManager.cs b/src/XamarinVirtualMachineManager.cs index 97e1d06..a98da8e 100644 --- a/src/XamarinVirtualMachineManager.cs +++ b/src/XamarinVirtualMachineManager.cs @@ -16,12 +16,10 @@ public static class XamarinVirtualMachineManager private const string START_DEBUGGER_COMMAND = "start debugger: sdb"; private const string CONNECT_STDOUT_COMMAND = "connect stdout"; - private delegate VirtualMachine LaunchCallback (ITargetProcess p, ProcessStartInfo info, Socket socket, TextWriter logWriter); - private delegate VirtualMachine ListenCallback (Socket dbg_sock, Socket con_sock, TextWriter logWriter); - private delegate VirtualMachine ConnectCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); - private delegate VirtualMachine ConnectCallbackWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter); + private delegate VirtualMachine ConnectWithNetworkOutputCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); + private delegate VirtualMachine ConnectWithConsoleCallback (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter); - private static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { + private static VirtualMachine ConnectWithNetworkOutput (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { if (con_sock != null) { try { @@ -54,7 +52,7 @@ private static VirtualMachine ConnectInternal (Socket dbg_sock, Socket con_sock, return VirtualMachineManager.Connect (transport, console, null); } - private static VirtualMachine ConnectInternalWithCustomConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) + private static VirtualMachine ConnectWithConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) { dbg_sock.Connect (dbg_ep); SendCommand(dbg_sock, START_DEBUGGER_COMMAND); @@ -70,26 +68,25 @@ private static void SendCommand(Socket socket, string command) socket.Send(commandBin, 0, commandBin.Length, SocketFlags.None); } - public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, IPEndPoint con_ep, AsyncCallback callback, TextWriter logWriter = null) { - Socket dbg_sock = null; - Socket con_sock = null; + public static IAsyncResult BeginConnect (IPEndPoint debugEndPoint, IPEndPoint outputEndPoint, AsyncCallback callback, TextWriter logWriter = null) { + Socket debugSocket = null; + Socket outputSocket = null; - dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - if (con_ep != null) { - con_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + debugSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + if (outputEndPoint != null) { + outputSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } - ConnectCallback c = new ConnectCallback (ConnectInternal); - return c.BeginInvoke (dbg_sock, con_sock, dbg_ep, con_ep, logWriter, callback, con_sock ?? dbg_sock); + ConnectWithNetworkOutputCallback c = new ConnectWithNetworkOutputCallback (ConnectWithNetworkOutput); + return c.BeginInvoke (debugSocket, outputSocket, debugEndPoint, outputEndPoint, logWriter, callback, outputSocket ?? debugSocket); } - public static IAsyncResult BeginConnect (IPEndPoint dbg_ep, StreamReader console, AsyncCallback callback, TextWriter logWriter = null) { - Socket dbg_sock = null; - dbg_sock = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); + public static IAsyncResult BeginConnect (IPEndPoint debugEndPoint, StreamReader console, AsyncCallback callback, TextWriter logWriter = null) { + Socket debugSocket = null; + debugSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - ConnectCallbackWithCustomConsole c = new ConnectCallbackWithCustomConsole (ConnectInternalWithCustomConsole); - return c.BeginInvoke (dbg_sock, dbg_ep, console, logWriter, callback, dbg_sock); + ConnectWithConsoleCallback c = new ConnectWithConsoleCallback (ConnectWithConsole); + return c.BeginInvoke (debugSocket, debugEndPoint, console, logWriter, callback, debugSocket); } public static VirtualMachine EndConnect (IAsyncResult asyncResult) { @@ -100,13 +97,13 @@ public static VirtualMachine EndConnect (IAsyncResult asyncResult) { asyncResult.AsyncWaitHandle.WaitOne (); AsyncResult result = (AsyncResult) asyncResult; - ConnectCallback cb = (ConnectCallback) result.AsyncDelegate; - return cb.EndInvoke (asyncResult); + ConnectWithNetworkOutputCallback cb = (ConnectWithNetworkOutputCallback) result.AsyncDelegate; + return cb.EndInvoke(asyncResult); } public static void CancelConnection (IAsyncResult asyncResult) { - ((Socket)asyncResult.AsyncState).Close (); + ((IDisposable) asyncResult.AsyncState).Dispose(); } } } From a312552a36513e778720ef2efc11030a3f0cc84b Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Wed, 4 Oct 2017 16:27:43 +0300 Subject: [PATCH 13/14] fixed logcat call --- src/MonoDebugSession.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MonoDebugSession.cs b/src/MonoDebugSession.cs index 29d9caf..ec7242e 100644 --- a/src/MonoDebugSession.cs +++ b/src/MonoDebugSession.cs @@ -1,4 +1,4 @@ -/*--------------------------------------------------------------------------------------------- +/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ @@ -449,7 +449,7 @@ public void LaunchXamarinAndroid(Response response, dynamic args) lock (_lock) { _debuggeeKilled = false; - var console = RunAdb("shell mono-stdout:D *:S"); + var console = RunAdb("shell logcat mono-stdout:D *:S"); var args0 = new XamarinDebuggerArgs(port, console) { MaxConnectionAttempts = MAX_CONNECTION_ATTEMPTS, TimeBetweenConnectionAttempts = CONNECTION_ATTEMPT_INTERVAL From dcc7e1eae233cd2f68170fd6c11f1ebdf9381a70 Mon Sep 17 00:00:00 2001 From: Vadzim Vysotski Date: Wed, 4 Oct 2017 21:17:01 +0300 Subject: [PATCH 14/14] added debug output for andoir --- src/XamarinConnectionProvider.cs | 18 ++------- src/XamarinVirtualMachineManager.cs | 63 ++++------------------------- 2 files changed, 11 insertions(+), 70 deletions(-) diff --git a/src/XamarinConnectionProvider.cs b/src/XamarinConnectionProvider.cs index f6aa1e6..6e7d197 100644 --- a/src/XamarinConnectionProvider.cs +++ b/src/XamarinConnectionProvider.cs @@ -11,28 +11,18 @@ namespace VSCodeDebug { public class XamarinConnectionProvider : ISoftDebuggerConnectionProvider { - private readonly int _port; + private readonly IPEndPoint _endPoint; private readonly StreamReader _console; public XamarinConnectionProvider(int port, StreamReader console = null) { - _port = port; + _endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), port); _console = console; } public IAsyncResult BeginConnect(DebuggerStartInfo dsi, AsyncCallback callback) - { - IAsyncResult result; - var endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), _port); - if (_console != null) - { - result = XamarinVirtualMachineManager.BeginConnect(endPoint, _console, callback); - } - else - { - result = XamarinVirtualMachineManager.BeginConnect(endPoint, endPoint, callback); - } - return result; + { + return XamarinVirtualMachineManager.BeginConnect(_endPoint, _console, callback); } public void CancelConnect(IAsyncResult result) diff --git a/src/XamarinVirtualMachineManager.cs b/src/XamarinVirtualMachineManager.cs index a98da8e..7010aec 100644 --- a/src/XamarinVirtualMachineManager.cs +++ b/src/XamarinVirtualMachineManager.cs @@ -16,44 +16,9 @@ public static class XamarinVirtualMachineManager private const string START_DEBUGGER_COMMAND = "start debugger: sdb"; private const string CONNECT_STDOUT_COMMAND = "connect stdout"; - private delegate VirtualMachine ConnectWithNetworkOutputCallback (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter); - private delegate VirtualMachine ConnectWithConsoleCallback (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter); + private delegate VirtualMachine ConnectWithConsoleOutputCallback (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter); - private static VirtualMachine ConnectWithNetworkOutput (Socket dbg_sock, Socket con_sock, IPEndPoint dbg_ep, IPEndPoint con_ep, TextWriter logWriter = null) { - if (con_sock != null) { - try - { - con_sock.Connect(con_ep); - SendCommand(con_sock, CONNECT_STDOUT_COMMAND); - } - catch (Exception) { - try { - dbg_sock.Close (); - } catch { } - throw; - } - } - - try { - dbg_sock.Connect (dbg_ep); - SendCommand(dbg_sock, START_DEBUGGER_COMMAND); - } catch (Exception) { - if (con_sock != null) { - try { - con_sock.Close (); - } catch { } - } - throw; - } - - Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); - StreamReader console = con_sock != null ? new StreamReader (new NetworkStream (con_sock)) : null; - - return VirtualMachineManager.Connect (transport, console, null); - } - - private static VirtualMachine ConnectWithConsole (Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) - { + private static VirtualMachine ConnectWithConsoleOutput(Socket dbg_sock, IPEndPoint dbg_ep, StreamReader console, TextWriter logWriter = null) { dbg_sock.Connect (dbg_ep); SendCommand(dbg_sock, START_DEBUGGER_COMMAND); Connection transport = new XamarinTcpConnection (dbg_sock, logWriter); @@ -68,28 +33,14 @@ private static void SendCommand(Socket socket, string command) socket.Send(commandBin, 0, commandBin.Length, SocketFlags.None); } - public static IAsyncResult BeginConnect (IPEndPoint debugEndPoint, IPEndPoint outputEndPoint, AsyncCallback callback, TextWriter logWriter = null) { - Socket debugSocket = null; - Socket outputSocket = null; - - debugSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - if (outputEndPoint != null) { - outputSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - } - - ConnectWithNetworkOutputCallback c = new ConnectWithNetworkOutputCallback (ConnectWithNetworkOutput); - return c.BeginInvoke (debugSocket, outputSocket, debugEndPoint, outputEndPoint, logWriter, callback, outputSocket ?? debugSocket); - } - - public static IAsyncResult BeginConnect (IPEndPoint debugEndPoint, StreamReader console, AsyncCallback callback, TextWriter logWriter = null) { + public static IAsyncResult BeginConnect(IPEndPoint debugEndPoint, StreamReader console, AsyncCallback callback, TextWriter logWriter = null) { Socket debugSocket = null; debugSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); - - ConnectWithConsoleCallback c = new ConnectWithConsoleCallback (ConnectWithConsole); + ConnectWithConsoleOutputCallback c = new ConnectWithConsoleOutputCallback (ConnectWithConsoleOutput); return c.BeginInvoke (debugSocket, debugEndPoint, console, logWriter, callback, debugSocket); } - public static VirtualMachine EndConnect (IAsyncResult asyncResult) { + public static VirtualMachine EndConnect(IAsyncResult asyncResult) { if (asyncResult == null) throw new ArgumentNullException ("asyncResult"); @@ -97,11 +48,11 @@ public static VirtualMachine EndConnect (IAsyncResult asyncResult) { asyncResult.AsyncWaitHandle.WaitOne (); AsyncResult result = (AsyncResult) asyncResult; - ConnectWithNetworkOutputCallback cb = (ConnectWithNetworkOutputCallback) result.AsyncDelegate; + ConnectWithConsoleOutputCallback cb = (ConnectWithConsoleOutputCallback) result.AsyncDelegate; return cb.EndInvoke(asyncResult); } - public static void CancelConnection (IAsyncResult asyncResult) + public static void CancelConnection(IAsyncResult asyncResult) { ((IDisposable) asyncResult.AsyncState).Dispose(); }