diff --git a/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs b/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs index b366cd8a408..eab1f812555 100644 --- a/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs +++ b/src/Mono.Android/Android.Runtime/JNINativeWrapper.cs @@ -13,7 +13,7 @@ public static class JNINativeWrapper { static void get_runtime_types () { - if (mono_unhandled_exception_method != null) + if (exception_handler_method != null) return; #if MONOANDROID1_0 mono_unhandled_exception_method = typeof (System.Diagnostics.Debugger).GetMethod ( @@ -70,10 +70,10 @@ public static Delegate CreateDelegate (Delegate dlg) ig.Emit (OpCodes.Leave, label); bool filter = Debugger.IsAttached || !JNIEnv.PropagateExceptions; - if (filter) { + if (filter && mono_unhandled_exception_method != null) { ig.BeginExceptFilterBlock (); - ig.Emit (OpCodes.Call, mono_unhandled_exception_method!); + ig.Emit (OpCodes.Call, mono_unhandled_exception_method); ig.Emit (OpCodes.Ldc_I4_1); ig.BeginCatchBlock (null!); } else { diff --git a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets index 0c72930ca3d..878294e8e10 100644 --- a/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets +++ b/src/Xamarin.Android.Build.Tasks/MSBuild/Xamarin/Android/Xamarin.Android.Bindings.Core.targets @@ -44,8 +44,6 @@ It is shared between "legacy" binding projects and .NET 5 projects. - - Off + + diff --git a/tests/MSBuildDeviceIntegration/Tests/XASdkDeployTests.cs b/tests/MSBuildDeviceIntegration/Tests/XASdkDeployTests.cs index f04359c1748..61168f19d2d 100644 --- a/tests/MSBuildDeviceIntegration/Tests/XASdkDeployTests.cs +++ b/tests/MSBuildDeviceIntegration/Tests/XASdkDeployTests.cs @@ -1,7 +1,12 @@ using System; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Net; using System.Reflection; +using System.Threading; +using Mono.Debugging.Client; +using Mono.Debugging.Soft; using NUnit.Framework; using Xamarin.ProjectTools; @@ -26,7 +31,6 @@ public void DotNetInstallAndRun ([Values (false, true)] bool isRelease, [Values IsRelease = isRelease }; } - proj.SetProperty (KnownProperties.AndroidSupportedAbis, DeviceAbi); proj.SetRuntimeIdentifier (DeviceAbi); var relativeProjDir = Path.Combine ("temp", TestName); @@ -43,5 +47,77 @@ public void DotNetInstallAndRun ([Values (false, true)] bool isRelease, [Values RunAdbCommand ($"uninstall {proj.PackageName}"); Assert.IsTrue(didLaunch, "Activity should have started."); } + + [Test] + public void DotNetDebug () + { + if (!HasDevices) + Assert.Ignore ("Skipping Test. No devices available."); + + XASdkProject proj; + proj = new XASdkProject (); + proj.SetRuntimeIdentifier (DeviceAbi); + + var relativeProjDir = Path.Combine ("temp", TestName); + var fullProjDir = Path.Combine (Root, relativeProjDir); + TestOutputDirectories [TestContext.CurrentContext.Test.ID] = fullProjDir; + var files = proj.Save (); + proj.Populate (relativeProjDir, files); + proj.CopyNuGetConfig (relativeProjDir); + var dotnet = new DotNetCLI (proj, Path.Combine (fullProjDir, proj.ProjectFilePath)); + Assert.IsTrue (dotnet.Build ("Install"), "`dotnet build` should succeed"); + + bool breakpointHit = false; + ManualResetEvent resetEvent = new ManualResetEvent (false); + var sw = new Stopwatch (); + // setup the debugger + var session = new SoftDebuggerSession (); + session.Breakpoints = new BreakpointStore { + { Path.Combine (Root, dotnet.ProjectDirectory, "MainActivity.cs"), 19 }, + }; + session.TargetHitBreakpoint += (sender, e) => { + Console.WriteLine ($"BREAK {e.Type}"); + breakpointHit = true; + session.Continue (); + }; + var rnd = new Random (); + int port = rnd.Next (10000, 20000); + TestContext.Out.WriteLine ($"{port}"); + var args = new SoftDebuggerConnectArgs ("", IPAddress.Loopback, port) { + MaxConnectionAttempts = 10, + }; + var startInfo = new SoftDebuggerStartInfo (args) { + WorkingDirectory = Path.Combine (dotnet.ProjectDirectory, proj.IntermediateOutputPath, "android", "assets"), + }; + var options = new DebuggerSessionOptions () { + EvaluationOptions = EvaluationOptions.DefaultOptions, + }; + options.EvaluationOptions.UseExternalTypeResolver = true; + ClearAdbLogcat (); + Assert.True (dotnet.Build ("_Run", new string [] { + $"AndroidSdbTargetPort={port}", + $"AndroidSdbHostPort={port}", + "AndroidAttachDebugger=True", + }), "Project should have run."); + + Assert.IsTrue (WaitForDebuggerToStart (Path.Combine (Root, dotnet.ProjectDirectory, "logcat.log")), "Activity should have started"); + // we need to give a bit of time for the debug server to start up. + WaitFor (2000); + session.LogWriter += (isStderr, text) => { Console.WriteLine (text); }; + session.OutputWriter += (isStderr, text) => { Console.WriteLine (text); }; + session.DebugWriter += (level, category, message) => { Console.WriteLine (message); }; + session.Run (startInfo, options); + WaitFor (TimeSpan.FromSeconds (30), () => session.IsConnected); + Assert.True (session.IsConnected, "Debugger should have connected but it did not."); + // we need to wait here for a while to allow the breakpoints to hit + // but we need to timeout + TimeSpan timeout = TimeSpan.FromSeconds (60); + while (session.IsConnected && !breakpointHit && timeout >= TimeSpan.Zero) { + Thread.Sleep (10); + timeout = timeout.Subtract (TimeSpan.FromMilliseconds (10)); + } + WaitFor (2000); + Assert.IsTrue (breakpointHit, "Should have a breakpoint"); + } } }