From bf40f74e45ad6984affec46e890615231782800f Mon Sep 17 00:00:00 2001 From: Dean Ellis Date: Wed, 21 Mar 2018 17:53:47 +0000 Subject: [PATCH] [Xamarin.Android.Build.Tasks] Add Locking for processing aapt output. We got a bug report where Aapt crashes with the following Unhandled Exception: System.ArgumentOutOfRangeException: capacity was less than the current size. Parameter name: value at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource) at System.Collections.Generic.List`1.set_Capacity(Int32 value) at System.Collections.Generic.List`1.EnsureCapacity(Int32 min) at System.Collections.Generic.List`1.Add(T item) at Xamarin.Android.Tasks.Aapt.<>c__DisplayClass134_0.b__0(Object sender, DataReceivedEventArgs e) This looks like a problem were the StdOut and StdError message handlers are being called a the same time. As a result they try to add and item at the same time causing this problem when the collection tries to grow. So lets put in some locks to ensure that only one message handler can add an item at a time. --- src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs index d72c1b423f4..3be2def229b 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/Aapt.cs @@ -126,17 +126,19 @@ bool RunAapt (string commandLine, IList output) CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden, }; - + object lockObject = new object (); using (var proc = new Process ()) { proc.OutputDataReceived += (sender, e) => { if (e.Data != null) - output.Add (new OutputLine (e.Data, stdError: false)); + lock (lockObject) + output.Add (new OutputLine (e.Data, stdError: false)); else stdout_completed.Set (); }; proc.ErrorDataReceived += (sender, e) => { if (e.Data != null) - output.Add (new OutputLine (e.Data, stdError: true)); + lock (lockObject) + output.Add (new OutputLine (e.Data, stdError: true)); else stderr_completed.Set (); };