Commit e88ea25
[Xamarin.Android.Build.Tasks] IOException & Console.InputEncoding (#4735)
Fixes: https://dev.azure.com/devdiv/DevDiv/_workitems/edit/1130414
Context: 0d6fd83
For some unknown reason setting the [`Console.InputEncoding`][0]
property on a customer's machine is throwing an `IOException`.
This causes Visual Studio (Windows) to completely crash:
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.IOException
at System.IO.__Error.WinIOError(Int32, System.String)
at System.IO.__Error.WinIOError()
at System.Console.set_InputEncoding(System.Text.Encoding)
at Xamarin.Android.Tasks.Aapt2Daemon.Aapt2DaemonStart()
at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Threading.ThreadHelper.ThreadStart()
The cause of the crash is that commit 0d6fd83 sets
`Console.InputEncoding` to "UTF-8 without BOM" for communication with
`aapt2`, so that we can sanely use Unicode paths, and setting
`Console.InputEncoding` may result in a `System.IO.IOException`.
(Paths are written to `Process.StandardInput`, which can contain
Unicode characters. `Console.InputEncoding` on the other hand,
defaults to "ANSI", which may not support full Unicode.)
Why did 0d6fd83 need to set `Console.InputEncoding` in the first
place? Because [`ProcessStartInfo.StandardInputEncoding`][1] wasn't
added until .NET Standard 2.1, and .NET Framework <= 4.8 doesn't
support .NET Standard 2.1, only .NET Standard 2.0. Furthermore,
when `ProcessStartInfo.RedirectStandardInput` is True,
[`Process.StandardInput` is a `StreamWriter`][2] which uses
`Console.InputEncoding` as the encoding for the underlying stream.
Thus, setting `Console.InputEncoding` is the only way in
.NET Standard 2.0/.NET Framework <= 4.8 to control the encoding used
by `Process.StandardInput`'s `StreamWriter`.
Further exploration since 0d6fd83 suggests that we could create a new
`StreamWriter` around `Process.StandardInput.BaseStream` with the
correct "UTF-8 without BOM" encoding, but that approach fails on CI:
…\Xamarin.Android.Aapt2.targets(124,3): error APT0001: Unknown option `-o`. Please check `$(AndroidAapt2CompileExtraArgs)` and `$(AndroidAapt2LinkExtraArgs)` to see if they include any `aapt` command line arguments that are no longer valid for `aapt2` and ensure that all other arguments are valid for `aapt2`.
…\Xamarin.Android.Aapt2.targets(124,3): error APT0001: Unknown option `-o`. Please check `$(AndroidAapt2CompileExtraArgs)` and `$(AndroidAapt2LinkExtraArgs)` to see if they include any `aapt` command line arguments that are no longer valid for `aapt2` and ensure that all other arguments are valid for `aapt2`.
…\Xamarin.Android.Aapt2.targets(124,3): error APT0001: Unknown option `-o`. Please check `$(AndroidAapt2CompileExtraArgs)` and `$(AndroidAapt2LinkExtraArgs)` to see if they include any `aapt` command line arguments that are no longer valid for `aapt2` and ensure that all other arguments are valid for `aapt2`.
…\Xamarin.Android.Aapt2.targets(124,3): error APT0001: Unknown option `-o`. Please check `$(AndroidAapt2CompileExtraArgs)` and `$(AndroidAapt2LinkExtraArgs)` to see if they include any `aapt` command line arguments that are no longer valid for `aapt2` and ensure that all other arguments are valid for `aapt2`.
We do not understand why this fails on CI unless
`Console.InputEncoding` is previously set.
All that said, we don't want Visual Studio to crash.
Fix the crash by:
1. Using System.Reflection to probe for
`ProcessStartInfo.StandardInputEncoding`. If it exists, use it.
2. If (2) fails, "fall back" and set `Console.InputEncoding` as
before, wrapping in a `try`/`catch` block so that `IOException`s
don't escape and crash Visual Studio.
TODO: We need to figure out a way of reporting this exception
somehow in the exception handler so we can get more data.
Regardless of whether (1) or (2) fails, as part of writing to `aapt2`s
`Process.StandardInput`, we wrap `Process.StandardInput.BaseStream`
into a new `StreamWriter` which uses "UTF-8 without BOM" as the
encoding. This is "defense in depth," though could plausibly result
in the previously mentioned APT0001 errors if setting
`Console.InputEncoding` failed.
We'll see what happens "in the wild."
[0]: https://docs.microsoft.com/en-us/dotnet/api/system.console.inputencoding?view=netcore-3.1
[1]: https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.standardinputencoding?view=netcore-3.1
[2]: https://referencesource.microsoft.com/#System/services/monitoring/system/diagnosticts/Process.cs,21541 parent d6e6062 commit e88ea25
1 file changed
+48
-18
lines changedLines changed: 48 additions & 18 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
| 11 | + | |
10 | 12 | | |
11 | 13 | | |
12 | 14 | | |
| |||
144 | 146 | | |
145 | 147 | | |
146 | 148 | | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
147 | 176 | | |
148 | 177 | | |
149 | 178 | | |
| |||
158 | 187 | | |
159 | 188 | | |
160 | 189 | | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
161 | 193 | | |
162 | 194 | | |
163 | | - | |
| 195 | + | |
164 | 196 | | |
165 | | - | |
166 | | - | |
167 | | - | |
168 | 197 | | |
169 | | - | |
170 | | - | |
| 198 | + | |
| 199 | + | |
171 | 200 | | |
172 | | - | |
| 201 | + | |
| 202 | + | |
173 | 203 | | |
174 | 204 | | |
175 | 205 | | |
176 | 206 | | |
177 | | - | |
| 207 | + | |
178 | 208 | | |
179 | 209 | | |
180 | 210 | | |
| |||
183 | 213 | | |
184 | 214 | | |
185 | 215 | | |
186 | | - | |
187 | | - | |
188 | | - | |
189 | | - | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
190 | 222 | | |
191 | | - | |
192 | | - | |
193 | 223 | | |
194 | | - | |
| 224 | + | |
195 | 225 | | |
196 | 226 | | |
197 | 227 | | |
| |||
201 | 231 | | |
202 | 232 | | |
203 | 233 | | |
204 | | - | |
205 | | - | |
| 234 | + | |
| 235 | + | |
206 | 236 | | |
207 | 237 | | |
208 | 238 | | |
| |||
256 | 286 | | |
257 | 287 | | |
258 | 288 | | |
259 | | - | |
| 289 | + | |
0 commit comments