Skip to content

Commit 855ad00

Browse files
dellis1972jonpryor
authored andcommitted
[Xamarin.Android.Build.Tests] Retry builds on native crashes (#993)
Sometimes when running `Xamarin.Android.Build.Tests`, mono crashes: Stacktrace: at <unknown> <0xffffffff> at (wrapper managed-to-native) object.__icall_wrapper_mono_gc_alloc_obj (intptr,intptr) [0x00000] in <4fdc5ed61a074cafb49fa42deb20d521>:0 at (wrapper alloc) object.AllocSmall (intptr,intptr) <0x000fa> at System.IO.FileSystemEnumerableIterator`1<TSource_REF>.CreateSearchResult (System.IO.Directory/SearchData,Microsoft.Win32.Win32Native/WIN32_FIND_DATA) [0x00023] in <4fdc5ed61a074cafb49fa42deb20d521>:0 # Actual stack trace doesn't *really* matter, and is basically random ... Native stacktrace: 0 mono 0x000000010d9df481 mono_handle_native_crash + 257 ... ================================================================= Got a SIGSEGV while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application. ================================================================= This is decidedly Not Good™. However, a significant percent of the time, the crash *also* isn't reproducible: a re-run of the build+tests will result in all tests passing. However, a re-run can take upwards of 2-6 *hours* -- depending mostly on whether the PR has a mono bump -- so it is undesirable to re-run builds just to see if it's a "random" error. Instead, update `Builder.BuildInternal()` so that if it determines that mono crashed -- via the `Got a SIGSEGV…` message -- then we'll re-try the crashing command. (Just once!) This should hopefully reduce the number of test failures we need to investigate. The *downside* is that the #runtime team would dearly love to know about these crashes, so *they* can investigate. This is *partially* supported by emitting the following message into the build output when a native crash is detected: Native crash detected! Running the build for … again. This is less than ideal, and may be improved in the future.
1 parent c43c5e6 commit 855ad00

File tree

1 file changed

+37
-22
lines changed
  • src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common

1 file changed

+37
-22
lines changed

src/Xamarin.Android.Build.Tasks/Tests/Xamarin.ProjectTools/Common/Builder.cs

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -241,37 +241,52 @@ protected bool BuildInternal (string projectOrSolution, string target, string []
241241
psi.RedirectStandardError = true;
242242
psi.StandardErrorEncoding = Encoding.UTF8;
243243
psi.StandardOutputEncoding = Encoding.UTF8;
244-
var p = Process.Start (psi);
245-
var ranToCompletion = p.WaitForExit ((int)new TimeSpan (0,10,0).TotalMilliseconds);
246-
var result = ranToCompletion && p.ExitCode == 0;
247244

248-
LastBuildTime = DateTime.UtcNow - start;
245+
bool nativeCrashDetected = false;
246+
bool result = false;
247+
int attempts = 1;
248+
for (int attempt = 0; attempt < attempts; attempt++) {
249+
var p = Process.Start (psi);
250+
var ranToCompletion = p.WaitForExit ((int)new TimeSpan (0, 10, 0).TotalMilliseconds);
251+
result = ranToCompletion && p.ExitCode == 0;
249252

250-
var sb = new StringBuilder ();
251-
sb.AppendLine ( psi.FileName + " " + args.ToString () + Environment.NewLine);
252-
if (!ranToCompletion)
253-
sb.AppendLine ("Build Timed Out!");
254-
if (buildLogFullPath != null && File.Exists (buildLogFullPath)) {
255-
using (var fs = File.OpenRead (buildLogFullPath)) {
256-
using (var sr = new StreamReader (fs, Encoding.UTF8, true, 65536)) {
257-
string line;
258-
while ((line = sr.ReadLine ()) != null) {
259-
sb.AppendLine (line);
260-
if (line.StartsWith ("Time Elapsed", StringComparison.OrdinalIgnoreCase)) {
261-
var match = timeElapsedRegEx.Match (line);
262-
if (match.Success) {
263-
LastBuildTime = TimeSpan.Parse (match.Groups ["TimeSpan"].Value);
264-
Console.WriteLine ($"Found Time Elapsed {LastBuildTime}");
253+
LastBuildTime = DateTime.UtcNow - start;
254+
255+
var sb = new StringBuilder ();
256+
sb.AppendLine (psi.FileName + " " + args.ToString () + Environment.NewLine);
257+
if (!ranToCompletion)
258+
sb.AppendLine ("Build Timed Out!");
259+
if (buildLogFullPath != null && File.Exists (buildLogFullPath)) {
260+
using (var fs = File.OpenRead (buildLogFullPath)) {
261+
using (var sr = new StreamReader (fs, Encoding.UTF8, true, 65536)) {
262+
string line;
263+
while ((line = sr.ReadLine ()) != null) {
264+
sb.AppendLine (line);
265+
if (line.StartsWith ("Time Elapsed", StringComparison.OrdinalIgnoreCase)) {
266+
var match = timeElapsedRegEx.Match (line);
267+
if (match.Success) {
268+
LastBuildTime = TimeSpan.Parse (match.Groups ["TimeSpan"].Value);
269+
Console.WriteLine ($"Found Time Elapsed {LastBuildTime}");
270+
}
271+
}
272+
if (line.StartsWith ("Got a SIGSEGV while executing native code", StringComparison.OrdinalIgnoreCase)) {
273+
nativeCrashDetected = true;
274+
break;
265275
}
266276
}
267277
}
268278
}
269279
}
280+
sb.AppendFormat ("\n#stdout begin\n{0}\n#stdout end\n", p.StandardOutput.ReadToEnd ());
281+
sb.AppendFormat ("\n#stderr begin\n{0}\n#stderr end\n", p.StandardError.ReadToEnd ());
282+
283+
LastBuildOutput = sb.ToString ();
284+
if (!nativeCrashDetected) {
285+
Console.WriteLine ($"Native crash detected! Running the build for {projectOrSolution} again.");
286+
continue;
287+
}
270288
}
271-
sb.AppendFormat ("\n#stdout begin\n{0}\n#stdout end\n", p.StandardOutput.ReadToEnd ());
272-
sb.AppendFormat ("\n#stderr begin\n{0}\n#stderr end\n", p.StandardError.ReadToEnd ());
273289

274-
LastBuildOutput = sb.ToString ();
275290

276291
if (buildLogFullPath != null) {
277292
Directory.CreateDirectory (Path.GetDirectoryName (buildLogFullPath));

0 commit comments

Comments
 (0)