Merge remote-tracking branch 'origin/master' into mono-2018-10

This commit is contained in:
Rolf Bjarne Kvinge 2018-12-07 08:25:46 +01:00
Родитель 3ddadfb852 2e72e1aee0
Коммит 1cdfc65b38
13 изменённых файлов: 197 добавлений и 98 удалений

Просмотреть файл

@ -46,7 +46,7 @@ XCODE94_VERSION=9.4
XCODE94_URL=http://xamarin-storage/bot-provisioning/xcodes/Xcode_9.4.xip
XCODE94_DEVELOPER_ROOT=/Applications/Xcode94.app/Contents/Developer
# Minimum Mono version
# Minimum Mono version for building XI/XM
MIN_MONO_VERSION=5.20.0.85
MAX_MONO_VERSION=5.20.99
MIN_MONO_URL=https://xamjenkinsartifact.azureedge.net/build-package-osx-mono/2018-10/72/114f88aaf12f5b810e5b776099c1e8efdd0a5aac/MonoFramework-MDK-5.20.0.85.macos10.xamarin.universal.pkg

8
jenkins/Jenkinsfile поставляемый
Просмотреть файл

@ -319,13 +319,7 @@ def runXamarinMacTests (url, macOS, maccore_hash, xamarin_macios_hash)
def t = "dontlink (system)"
try {
// install oldest supported mono
sh ('''
cd mac-test-package
URL=`grep "^MIN_XM_MONO_URL=" Make.config | sed 's/.*=//'`
curl -L "$URL" --output old-mono.pkg
sudo installer -pkg old-mono.pkg -target /
mono --version
''')
sh ("./prepare-packaged-macos-tests.sh --install-old-mono")
// run dontlink tests using the system mono
sh ("make -C mac-test-package/tests exec-mac-system-dontlink")
} catch (error) {

Просмотреть файл

@ -2,6 +2,35 @@
# don't change the current directory here
if [[ "$1" == "--install-old-mono" ]]; then
cd mac-test-package
URL=$(grep "^MIN_XM_MONO_URL=" Make.config | sed 's/.*=//')
COUNTER=0
echo "Downloading and installing $URL"
while [[ $COUNTER -lt 5 ]]; do
EC=0
curl -s -L "$URL" --output old-mono.pkg || EC=$?
if [[ $EC -eq 56 ]]; then
# Sometimes we get spurious "curl: (56) SSLRead() return error -9806" errors. Trying again usually works, so lets try again a few more times.
# https://github.com/xamarin/maccore/issues/1098
let COUNTER++ || true
continue
fi
break
done
if [[ "x$EC" != "x0" ]]; then
echo "Failed to provision old mono (exit code: $EC)"
exit $EC
fi
sudo installer -pkg old-mono.pkg -target /
mono --version
exit 0
fi
URL=$1
MACCORE_HASH=$2
if test -z "$URL"; then
@ -29,8 +58,8 @@ unzip -o mac-test-package.zip
cd mac-test-package
COUNTER=0
EC=0
while [[ $COUNTER -lt 5 ]]; do
EC=0
./system-dependencies.sh --provision-mono --ignore-autotools --ignore-xamarin-studio --ignore-xcode --ignore-osx --ignore-cmake || EC=$?
if [[ $EC -eq 56 ]]; then
# Sometimes we get spurious "curl: (56) SSLRead() return error -9806" errors. Trying again usually works, so lets try again a few more times.

Просмотреть файл

@ -1,5 +1,5 @@
ifdef ENABLE_XAMARIN
NEEDED_MACCORE_VERSION := 6e9b63e53755a74138b78dafd098836a79660edd
NEEDED_MACCORE_VERSION := e3d92b50d6beb38b154a3dfe9242720c67f8d7c3
NEEDED_MACCORE_BRANCH := master
MACCORE_DIRECTORY := maccore

Просмотреть файл

@ -119,7 +119,6 @@ namespace ImageCaptureCore {
[Field ("ICStatusNotificationKey")]
NSString NotificationKey { get; }
[Mac (10, 8)]
[Field ("ICStatusCodeKey")]
NSString CodeKey { get; }

Просмотреть файл

@ -59,7 +59,6 @@ namespace MonoTests.System.Net.Http
HttpClient client = new HttpClient (GetHandler (handlerType));
var s = await client.GetStringAsync ("http://doesnotexist.xamarin.com");
Console.WriteLine (s);
Assert.Fail ($"An exception should have been thrown, instead got:\n{s}");
} catch (Exception e) {
ex = e;
} finally {
@ -67,6 +66,7 @@ namespace MonoTests.System.Net.Http
}
}, () => done);
Assert.IsTrue (done, "Did not time out");
Assert.IsNotNull (ex, "Exception");
// The handlers throw different types of exceptions, so we can't assert much more than that something went wrong.
}

Просмотреть файл

@ -56,21 +56,20 @@ namespace xharness
public static class Process_Extensions
{
public static async Task<ProcessExecutionResult> RunAsync (this Process process, Log log, CancellationToken? cancellation_token = null)
public static async Task<ProcessExecutionResult> RunAsync (this Process process, Log log, CancellationToken? cancellation_token = null, bool? diagnostics = null)
{
return await RunAsync (process, log, log, log, cancellation_token: cancellation_token);
return await RunAsync (process, log, log, log, cancellation_token: cancellation_token, diagnostics: diagnostics);
}
public static Task<ProcessExecutionResult> RunAsync (this Process process, Log log, bool append = true, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null)
public static Task<ProcessExecutionResult> RunAsync (this Process process, Log log, bool append = true, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null)
{
return RunAsync (process, log, log, log, timeout, environment_variables, cancellation_token);
return RunAsync (process, log, log, log, timeout, environment_variables, cancellation_token, diagnostics);
}
public static async Task<ProcessExecutionResult> RunAsync (this Process process, Log log, TextWriter StdoutStream, TextWriter StderrStream, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null)
public static async Task<ProcessExecutionResult> RunAsync (this Process process, Log log, TextWriter StdoutStream, TextWriter StderrStream, TimeSpan? timeout = null, Dictionary<string, string> environment_variables = null, CancellationToken? cancellation_token = null, bool? diagnostics = null)
{
var stdout_completion = new TaskCompletionSource<bool> ();
var stderr_completion = new TaskCompletionSource<bool> ();
var exit_completion = new TaskCompletionSource<bool> ();
var rv = new ProcessExecutionResult ();
process.StartInfo.RedirectStandardError = true;
@ -123,37 +122,28 @@ namespace xharness
log.WriteLine (sb);
process.Start ();
var pid = process.Id;
process.BeginErrorReadLine ();
process.BeginOutputReadLine ();
cancellation_token?.Register (() => {
if (!exit_completion.Task.IsCompleted) {
if (!process.HasExited) {
StderrStream.WriteLine ($"Execution was cancelled.");
ProcessHelper.kill (process.Id, 9);
}
});
new Thread (() =>
{
if (timeout.HasValue) {
if (!process.WaitForExit ((int) timeout.Value.TotalMilliseconds)) {
process.KillTreeAsync (log, true).Wait ();
rv.TimedOut = true;
lock (StderrStream)
log.WriteLine ($"Execution timed out after {timeout.Value.TotalSeconds} seconds and the process was killed.");
}
if (timeout.HasValue) {
if (!await process.WaitForExitAsync (timeout.Value)) {
await process.KillTreeAsync (log, diagnostics ?? true);
rv.TimedOut = true;
lock (StderrStream)
log.WriteLine ($"{pid} Execution timed out after {timeout.Value.TotalSeconds} seconds and the process was killed.");
}
process.WaitForExit ();
exit_completion.TrySetResult (true);
Task.WaitAll (new Task [] { stderr_completion.Task, stdout_completion.Task }, TimeSpan.FromSeconds (1));
stderr_completion.TrySetResult (false);
stdout_completion.TrySetResult (false);
}) {
IsBackground = true,
}.Start ();
await Task.WhenAll (stderr_completion.Task, stdout_completion.Task, exit_completion.Task);
}
await process.WaitForExitAsync ();
Task.WaitAll (new Task [] { stderr_completion.Task, stdout_completion.Task }, TimeSpan.FromSeconds (1));
try {
rv.ExitCode = process.ExitCode;
@ -164,22 +154,54 @@ namespace xharness
return rv;
}
public static Task KillTreeAsync (this Process @this, Log log, bool diagnostics = true)
public async static Task<bool> WaitForExitAsync (this Process process, TimeSpan? timeout = null)
{
if (process.HasExited)
return true;
var tcs = new TaskCompletionSource<bool> ();
void ProcessExited (object sender, EventArgs ea)
{
process.Exited -= ProcessExited;
tcs.TrySetResult (true);
}
process.Exited += ProcessExited;
process.EnableRaisingEvents = true;
// Check if process exited again, in case it exited after we checked
// the last time, but before we attached the event handler.
if (process.HasExited) {
process.Exited -= ProcessExited;
tcs.TrySetResult (true);
return true;
}
if (timeout.HasValue) {
return await tcs.Task.TimeoutAfter (timeout.Value);
} else {
await tcs.Task;
return true;
}
}
public static Task KillTreeAsync (this Process @this, Log log, bool? diagnostics = true)
{
return KillTreeAsync (@this.Id, log, diagnostics);
}
public static async Task KillTreeAsync (int pid, Log log, bool diagnostics = true)
public static async Task KillTreeAsync (int pid, Log log, bool? diagnostics = true)
{
var pids = new List<int> ();
GetChildrenPS (log, pids, pid);
if (diagnostics) {
if (diagnostics == true) {
log.WriteLine ($"Pids to kill: {string.Join (", ", pids.Select ((v) => v.ToString ()).ToArray ())}");
using (var ps = new Process ()) {
log.WriteLine ("Writing process list:");
ps.StartInfo.FileName = "ps";
ps.StartInfo.Arguments = "-A -o pid,ruser,ppid,pgid,%cpu=%CPU,%mem=%MEM,flags=FLAGS,lstart,rss,vsz,tty,state,time,command";
await ps.RunAsync (log, true, TimeSpan.FromSeconds (5));
await ps.RunAsync (log, true, TimeSpan.FromSeconds (5), diagnostics: false);
}
foreach (var diagnose_pid in pids) {
@ -197,7 +219,7 @@ namespace xharness
File.WriteAllText (template, commands.ToString ());
log.WriteLine ($"Printing backtrace for pid={pid}");
await dbg.RunAsync (log, true, TimeSpan.FromSeconds (30));
await dbg.RunAsync (log, true, TimeSpan.FromSeconds (30), diagnostics: false);
}
} finally {
try {
@ -209,20 +231,14 @@ namespace xharness
}
}
using (var kill = new Process ()) {
kill.StartInfo.FileName = "kill";
// Send SIGABRT since that produces a crash report
// lldb may fail to attach to system processes, but crash reports will still be produced with potentially helpful stack traces.
kill.StartInfo.Arguments = "-6 " + string.Join (" ", pids.Select ((v) => v.ToString ()).ToArray ());
await kill.RunAsync (log, true, TimeSpan.FromSeconds (2.5));
}
// Send SIGABRT since that produces a crash report
// lldb may fail to attach to system processes, but crash reports will still be produced with potentially helpful stack traces.
for (int i = 0; i < pids.Count; i++)
ProcessHelper.kill (pids [i], 6);
using (var kill = new Process ()) {
kill.StartInfo.FileName = "kill";
// send kill -9 anyway as a last resort
kill.StartInfo.Arguments = "-9 " + string.Join (" ", pids.Select ((v) => v.ToString ()).ToArray ());
await kill.RunAsync (log, true, TimeSpan.FromSeconds (2.5));
}
// send kill -9 anyway as a last resort
for (int i = 0; i < pids.Count; i++)
ProcessHelper.kill (pids [i], 9);
}
static void GetChildrenPS (Log log, List<int> list, int pid)

Просмотреть файл

@ -397,5 +397,43 @@ namespace Extrospection {
else
return (o1, o2);
}
public enum ArgumentSemantic {
None = -1,
Assign = 0,
Copy = 1,
Retain = 2,
Weak = 3,
Strong = Retain,
UnsafeUnretained = Assign,
}
public static ArgumentSemantic ToArgumentSemantic (this ObjCPropertyAttributeKind attr)
{
if ((attr & ObjCPropertyAttributeKind.Retain) != 0)
return ArgumentSemantic.Retain;
else if ((attr & ObjCPropertyAttributeKind.Copy) != 0)
return ArgumentSemantic.Copy;
else if ((attr & ObjCPropertyAttributeKind.Assign) != 0)
return ArgumentSemantic.Assign;
else if ((attr & ObjCPropertyAttributeKind.Weak) != 0)
return ArgumentSemantic.Weak;
else if ((attr & ObjCPropertyAttributeKind.Strong) != 0)
return ArgumentSemantic.Strong;
else if ((attr & ObjCPropertyAttributeKind.UnsafeUnretained) != 0)
return ArgumentSemantic.UnsafeUnretained;
else
return ArgumentSemantic.Assign; // Default
}
public static string ToUsableString (this ArgumentSemantic argSem)
{
if (argSem == ArgumentSemantic.Retain)
return "Strong|Retain";
if (argSem == ArgumentSemantic.Assign)
return "UnsafeUnretained|Assign";
return argSem.ToString ();
}
}
}

Просмотреть файл

@ -4,9 +4,6 @@
// !missing-selector!
// if headers defines a selector for which we have no bindings
//
// !unknown-selector!
// if we have a selector that is not part of the header files
//
using System;
using System.Collections.Generic;
@ -18,24 +15,9 @@ using Clang.Ast;
namespace Extrospection {
public class SelectorCheck : BaseVisitor {
// Dictionary<string,List<MethodDefinition>> exports = new Dictionary<string, List<MethodDefinition>> ();
// missing
// -> it's not in the type or ancestor or their interface (protocols)
// -> it's not in a category
// unknown
// -> quick check (HashSet) to see if it's used anywhere
// ->
// duplicate
// -> the selector is defined more than once for the same type
HashSet<string> known_selectors = new HashSet<string> ();
HashSet<string> qualified_selectors = new HashSet<string> ();
//Dictionary<TypeDefinition,HashSet<string>> type_exports = new Dictionary<TypeDefinition,HashSet<string>> ();
Dictionary<string, Helpers.ArgumentSemantic> qualified_properties = new Dictionary<string, Helpers.ArgumentSemantic> ();
// most selectors will be found in [Export] attribtues
public override void VisitManagedMethod (MethodDefinition method)
@ -51,24 +33,49 @@ namespace Extrospection {
foreach (var ca in method.CustomAttributes) {
switch (ca.Constructor.DeclaringType.Name) {
case "ExportAttribute":
string selector = ca.ConstructorArguments [0].Value as string;
if (!known_selectors.Contains (selector))
known_selectors.Add (selector);
var methodDefinition = method.GetName ();
if (!string.IsNullOrEmpty (methodDefinition)) {
var argumentSemantic = Helpers.ArgumentSemantic.Assign; // Default
if (ca.ConstructorArguments.Count > 1) {
argumentSemantic = (Helpers.ArgumentSemantic)ca.ConstructorArguments [1].Value;
qualified_properties.Add (methodDefinition, argumentSemantic);
}
qualified_selectors.Add (methodDefinition);
}
qualified_selectors.Add (method.GetName ());
//
// TypeDefinition type = method.DeclaringType;
// HashSet<string> list;
// if (!type_exports.TryGetValue (type, out list)) {
// list = new HashSet<string> ();
// type_exports.Add (type, list);
// }
// list.Add (selector);
break;
}
}
}
public override void VisitObjCPropertyDecl (ObjCPropertyDecl decl)
{
// protocol members are checked in ObjCProtocolCheck
if (decl.DeclContext is ObjCProtocolDecl)
return;
// check availability macros to see if the API is available on the OS and not deprecated
if (!decl.IsAvailable ())
return;
var framework = Helpers.GetFramework (decl);
if (framework == null)
return;
var nativeArgumentSemantic = decl.Attributes.ToArgumentSemantic ();
var nativeMethodDefinition = decl.QualifiedName;
bool found = qualified_properties.TryGetValue (nativeMethodDefinition, out var managedArgumentSemantic);
if (found && managedArgumentSemantic != nativeArgumentSemantic) {
// FIXME: only Copy mistakes are reported now
if (managedArgumentSemantic == Helpers.ArgumentSemantic.Copy || nativeArgumentSemantic == Helpers.ArgumentSemantic.Copy) {
// FIXME: rule disactivated for now
//Log.On (framework).Add ($"!incorrect-argument-semantic! Native '{nativeMethodDefinition}' is declared as ({nativeArgumentSemantic.ToUsableString ().ToLowerInvariant ()}) but mapped to 'ArgumentSemantic.{managedArgumentSemantic.ToUsableString ()}'");
}
}
}
public override void VisitObjCMethodDecl (ObjCMethodDecl decl, VisitKind visitKind)
{
if (visitKind != VisitKind.Enter)

Просмотреть файл

@ -122,7 +122,8 @@ namespace Xamarin.Bundler {
public static bool Force;
static bool is_extension;
static bool frameworks_copied_to_bundle_dir; // Have we copied any frameworks to Foo.app/Contents/Frameworks?
static bool frameworks_copied_to_bundle_dir; // Have we copied any frameworks to Foo.app/Contents/Frameworks?
static bool dylibs_copied_to_bundle_dir => native_libraries_copied_in.Count > 0;
const string pkg_config = "/Library/Frameworks/Mono.framework/Commands/pkg-config";
@ -828,7 +829,12 @@ namespace Xamarin.Bundler {
throw new MonoMacException (5103, true, String.Format ("Failed to compile. Error code - {0}. Please file a bug report at https://github.com/xamarin/xamarin-macios/issues/new", ret));
}
if (frameworks_copied_to_bundle_dir) {
int install_ret = XcodeRun ("install_name_tool", string.Format ("{0} -add_rpath @loader_path/../Frameworks", StringUtils.Quote (AppPath)));
int install_ret = XcodeRun ("install_name_tool", $"{StringUtils.Quote (AppPath)} -add_rpath @loader_path/../Frameworks");
if (install_ret != 0)
throw new MonoMacException (5310, true, "install_name_tool failed with an error code '{0}'. Check build log for details.", ret);
}
if (dylibs_copied_to_bundle_dir) {
int install_ret = XcodeRun ("install_name_tool", $"{StringUtils.Quote (AppPath)} -add_rpath @loader_path/../{BundleName}");
if (install_ret != 0)
throw new MonoMacException (5310, true, "install_name_tool failed with an error code '{0}'. Check build log for details.", ret);
}
@ -1587,7 +1593,9 @@ namespace Xamarin.Bundler {
case "winmm": // windows specific
case "winspool": // windows specific
case "c": // system provided
case "objc": // system provided
case "objc": // system provided
case "objc.a": // found in swift core libraries
case "system.b": // found in swift core libraries
case "system": // system provided, libSystem.dylib -> CommonCrypto
case "x11": // msvcrt pulled in
case "winspool.drv": // msvcrt pulled in
@ -1668,8 +1676,6 @@ namespace Xamarin.Bundler {
if (verbose > 1)
Console.WriteLine ("Native library '{0}' copied to application bundle.", Path.GetFileName (real_src));
// FIXME: should we strip extra architectures (e.g. x64) ?
// that could break the library signature and cause issues on the appstore :(
if (GetRealPath (dest) == real_src) {
Console.WriteLine ("Dependency {0} was already at destination, skipping.", Path.GetFileName (real_src));
}

Просмотреть файл

@ -290,6 +290,12 @@ namespace Xamarin.Bundler {
ProcessStartInfo = Driver.CreateStartInfo (App, aotCompiler, aotArgs, Path.GetDirectoryName (assembly_path)),
AotInfo = aotInfo,
};
if (App.Platform == ApplePlatform.WatchOS) {
// Visual Studio for Mac sets this environment variable, and it confuses the AOT compiler.
// So unset it.
// See https://github.com/mono/mono/issues/11765
task.ProcessStartInfo.EnvironmentVariables ["MONO_THREADS_SUSPEND"] = null;
}
aotInfo.Task = task;
}

Просмотреть файл

@ -112,7 +112,6 @@ namespace xibuild {
FileName = toolPath,
Arguments = combinedArgs,
UseShellExecute = false,
RedirectStandardInput = true,
});
p.WaitForExit ();

Просмотреть файл

@ -1,5 +1,10 @@
#!/bin/sh
ABSOLUTE_PATH=$(cd `dirname "${BASH_SOURCE[0]}"` && pwd)/`basename "${BASH_SOURCE[0]}"`
TOOL_DIR=`dirname $ABSOLUTE_PATH`
#!/bin/bash -e
mono $TOOL_DIR/bin/Debug/xibuild.exe "$@"
ABSOLUTE_PATH=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")
TOOL_DIR=$(dirname "$ABSOLUTE_PATH")
if ! test -f "$TOOL_DIR/bin/Debug/xibuild.exe"; then
make -C "$TOOL_DIR"
fi
mono "$TOOL_DIR/bin/Debug/xibuild.exe" "$@"