Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Ungureanu <teromario@yahoo.com>2018-07-25 12:16:17 +0300
committerMarek Safar <marek.safar@gmail.com>2018-07-25 12:16:17 +0300
commit6b2eafc39db5574bde9e7cf52914c888bb4a2578 (patch)
tree1c778cfb68581493e8970d892de64ab76d315346
parentd065dc9292e76af34fe2bce3ab2d629acbe1e38c (diff)
Fix up behaviour of verbose method with arguments (#9087)
* Fix up behaviour of verbose method with arguments Given a method spec which looks like: `MainClass:Do(int,int,int)` Via f024e820a025aacc1cf80eb82a8aee4552c3ac11 the code would match 3 methods: `MainClass:Do(int`, `int`, `int)`, crashing the runtime. Accept the multiple method matches via `;`, rather than `,`. Now, the behaviour is changed so: `MainClass:Do(int,int,int);MainClass:Do(int,int)` Get parsed as: `MainClass:Do(int,int,int)` `MainClass:Do(int,int)` * Add tests * add test file and make tests actually output something * Smarter unit test around disassembling methods * Try single quoting environment variable value * Try using non-throwing setter
-rw-r--r--man/mono.12
-rw-r--r--mono/mini/mini.c2
-rwxr-xr-xmono/tests/Makefile.am3
-rw-r--r--mono/tests/verbose.cs157
4 files changed, 161 insertions, 3 deletions
diff --git a/man/mono.1 b/man/mono.1
index 8f9f6439f79..7b9ae4eddf9 100644
--- a/man/mono.1
+++ b/man/mono.1
@@ -1897,7 +1897,7 @@ for example, to see managed frame names on gdb backtraces.
\fBMONO_VERBOSE_METHOD\fR
Enables the maximum JIT verbosity for the specified method. This is
very helpfull to diagnose a miscompilation problems of a specific
-method. This can be a comma-separated list of method names to
+method. This can be a semicolon-separated list of method names to
match. If the name is simple, this applies to any method with that
name, otherwise you can use a mono method description (see the section
METHOD DESCRIPTIONS).
diff --git a/mono/mini/mini.c b/mono/mini/mini.c
index 31cd462dcf8..e2e52fc66d4 100644
--- a/mono/mini/mini.c
+++ b/mono/mini/mini.c
@@ -3361,7 +3361,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl
if (!verbose_method_inited) {
char *env = g_getenv ("MONO_VERBOSE_METHOD");
if (env != NULL)
- verbose_method_names = g_strsplit (env, ",", -1);
+ verbose_method_names = g_strsplit (env, ";", -1);
verbose_method_inited = TRUE;
}
diff --git a/mono/tests/Makefile.am b/mono/tests/Makefile.am
index dbbaa669590..bc903e4e223 100755
--- a/mono/tests/Makefile.am
+++ b/mono/tests/Makefile.am
@@ -687,7 +687,8 @@ TESTS_CS_SRC= \
tailcall-interface.cs \
bug-60843.cs \
nested_type_visibility.cs \
- dynamic-method-churn.cs
+ dynamic-method-churn.cs \
+ verbose.cs
# some tests fail to compile on mcs
if CSC_IS_ROSLYN
diff --git a/mono/tests/verbose.cs b/mono/tests/verbose.cs
new file mode 100644
index 00000000000..2c609567dbf
--- /dev/null
+++ b/mono/tests/verbose.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Text.RegularExpressions;
+
+public class MainClass
+{
+ class TestCase
+ {
+ public string MethodSpec;
+ public string[] ExpectedMethods;
+ }
+
+ public static int Main (string[] args)
+ {
+ var testCase = new TestCase {
+ MethodSpec = "*:Method",
+ ExpectedMethods = new[] {
+ "N1.Test:Method ()",
+ "N2.Test:Method ()",
+ "N2.Test:Method (int)",
+ "N2.Test:Method (int,string[])",
+ },
+ };
+ if (!RunTest (testCase))
+ return 1;
+
+ testCase = new TestCase {
+ MethodSpec = "*:Method (int)",
+ ExpectedMethods = new[] {
+ "N2.Test:Method (int)",
+ },
+ };
+ if (!RunTest (testCase))
+ return 2;
+
+ testCase = new TestCase
+ {
+ MethodSpec = "N1.Test:Method",
+ ExpectedMethods = new[] {
+ "N1.Test:Method ()",
+ },
+ };
+ if (!RunTest (testCase))
+ return 3;
+
+ testCase = new TestCase {
+ MethodSpec = "Test:Method",
+ ExpectedMethods = new[] {
+ "N1.Test:Method ()",
+ "N2.Test:Method ()",
+ "N2.Test:Method (int)",
+ "N2.Test:Method (int,string[])",
+ },
+ };
+ if (!RunTest (testCase))
+ return 4;
+
+ testCase = new TestCase {
+ MethodSpec = "*:Method(int,string[])",
+ ExpectedMethods = new[] {
+ "N2.Test:Method (int,string[])",
+ },
+ };
+ if (!RunTest (testCase))
+ return 5;
+
+ testCase = new TestCase {
+ MethodSpec = "*:Method();N2.*:Method(int,string[])",
+ ExpectedMethods = new[] {
+ "N1.Test:Method ()",
+ "N2.Test:Method ()",
+ "N2.Test:Method (int,string[])",
+ },
+ };
+ if (!RunTest (testCase))
+ return 6;
+
+ return 0;
+ }
+
+ static bool RunTest (TestCase testCase)
+ {
+ var thisProcess = typeof (MainClass).Assembly.Location;
+
+ var process = StartCompileAssemblyProcess (thisProcess, testCase.MethodSpec);
+ var output = process.StandardOutput.ReadToEnd ();
+ process.WaitForExit ();
+
+ var lines = output.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ foreach (var expectedMethod in testCase.ExpectedMethods) {
+ var sortedExpectedMethods = testCase.ExpectedMethods.OrderBy (x => x).ToArray ();
+
+ var regex = new Regex ("converting method void (?<methodName>.*)");
+ var matches = regex.Matches (output);
+ var sortedJittedMethods = matches.Cast<Match> ().Select (x => x.Groups["methodName"])
+ .SelectMany (x => x.Captures.Cast<Capture> ())
+ .Select (x => x.Value)
+ .OrderBy (x => x)
+ .ToArray ();
+
+ if (sortedJittedMethods.Length != sortedExpectedMethods.Length)
+ return false;
+
+ for (int i = 0; i < sortedJittedMethods.Length; ++i) {
+ if (sortedJittedMethods[i] != sortedExpectedMethods[i])
+ return false;
+ }
+
+ }
+
+ return true;
+ }
+
+ static Process StartCompileAssemblyProcess (string process, string methodSpec)
+ {
+ var psi = new ProcessStartInfo (process) {
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ };
+ psi.EnvironmentVariables["MONO_ENV_OPTIONS"] = "--compile-all";
+ psi.EnvironmentVariables["MONO_VERBOSE_METHOD"] = methodSpec;
+
+ return Process.Start (psi);
+ }
+}
+
+namespace N1
+{
+ public class Test
+ {
+ public static void Method ()
+ {
+ }
+ }
+}
+
+namespace N2
+{
+ public class Test
+ {
+ public static void Method (int n)
+ {
+ }
+
+ public static void Method ()
+ {
+ }
+
+ public static void Method (int n, string[] args)
+ {
+ }
+ }
+}
+
+