summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/README.md4
-rw-r--r--Documentation/custom-dnx-instructions.md (renamed from Documentation/dnx-instructions.md)0
-rw-r--r--Documentation/freebsd-instructions.md202
-rw-r--r--Documentation/get-dotnetcore-windows-dnvm.md107
-rw-r--r--Documentation/get-dotnetcore-windows-nuget.md (renamed from Documentation/get-coreclr-windows.md)8
-rw-r--r--Documentation/windows-instructions.md4
-rw-r--r--README.md16
-rw-r--r--build.cmd26
-rw-r--r--src/ToolBox/SOS/Strike/eeheap.cpp4
-rw-r--r--src/ToolBox/SOS/Strike/gcroot.cpp22
-rw-r--r--src/ToolBox/SOS/Strike/strike.cpp2
-rw-r--r--src/ToolBox/SOS/Strike/util.cpp6
-rw-r--r--src/ToolBox/SOS/Strike/util.h20
-rw-r--r--src/ToolBox/SOS/lldbplugin/CMakeLists.txt2
-rw-r--r--src/ToolBox/SOS/lldbplugin/coreruncommand.cpp48
-rw-r--r--src/ToolBox/SOS/lldbplugin/debugclient.cpp2
-rw-r--r--src/ToolBox/SOS/lldbplugin/sosplugin.cpp4
-rw-r--r--src/ToolBox/SOS/lldbplugin/sosplugin.h5
-rw-r--r--src/coreclr/hosts/unixcorerun/CMakeLists.txt7
-rw-r--r--src/coreclr/hosts/unixcorerun/corerun.cpp9
-rw-r--r--src/debug/daccess/dacimpl.h8
-rw-r--r--src/mscorlib/src/System/IO/FileSecurityState.cs4
-rw-r--r--src/pal/src/exception/machexception.cpp70
-rw-r--r--src/pal/src/exception/seh.cpp19
-rw-r--r--src/pal/src/exception/signal.cpp449
-rw-r--r--src/pal/src/exception/signal.hpp6
-rw-r--r--src/pal/src/include/pal/seh.hpp4
-rw-r--r--src/pal/src/init/pal.cpp4
-rw-r--r--src/pal/src/thread/thread.cpp6
-rw-r--r--src/pal/src/thread/threadsusp.cpp82
-rw-r--r--src/pal/tools/gen-buildsys-win.bat10
-rw-r--r--src/vm/corhost.cpp4
-rw-r--r--src/vm/exceptionhandling.cpp31
-rw-r--r--tests/buildtest.cmd25
-rw-r--r--tests/runtest.cmd24
-rw-r--r--tests/runtest.proj17
36 files changed, 737 insertions, 524 deletions
diff --git a/Documentation/README.md b/Documentation/README.md
index 61c6caece8..ed655939ad 100644
--- a/Documentation/README.md
+++ b/Documentation/README.md
@@ -6,11 +6,13 @@ This repo includes several documents that explain both high-level and low-level
Get CoreCLR
===========
-- [Get CoreCLR on Windows](get-coreclr-windows.md)
+- [Get .NET Core on Windows - NuGet](get-dotnetcore-windows-nuget.md)
+- [Get .NET Core on Windows - .NET Version Manager](get-dotnetcore-windows-dnvm.md)
Build CoreCLR from Source
=========================
+- [Building CoreCLR on FreeBSD](freebsd-instructions.md)
- [Building CoreCLR on Linux](linux-instructions.md)
- [Building CoreCLR on OS X](osx-instructions.md)
- [Building CoreCLR on Windows](windows-instructions.md)
diff --git a/Documentation/dnx-instructions.md b/Documentation/custom-dnx-instructions.md
index 888f13dbd9..888f13dbd9 100644
--- a/Documentation/dnx-instructions.md
+++ b/Documentation/custom-dnx-instructions.md
diff --git a/Documentation/freebsd-instructions.md b/Documentation/freebsd-instructions.md
new file mode 100644
index 0000000000..9d5a4b910a
--- /dev/null
+++ b/Documentation/freebsd-instructions.md
@@ -0,0 +1,202 @@
+Build CoreCLR on FreeBSD
+======================
+
+This guide will walk you through building CoreCLR on FreeBSD and running Hello World. We'll start by showing how to set up your environment from scratch.
+
+Environment
+===========
+
+These instructions are written assuming FreeBSD 10.1-RELEASE, since that's the release the team uses.
+
+These instructions assume you use the binary package tool `pkg` (analog to `apt-get` or `yum` on Linux) to install the environment. Compiling the dependencies from source using the ports tree might work too, but is untested.
+
+Minimum RAM required to build is 1GB. The build is known to fail on 512 MB VMs ([Issue 536](https://github.com/dotnet/coreclr/issues/536)).
+
+Toolchain Setup
+---------------
+
+Install the following packages for the toolchain:
+
+- bash
+- cmake
+- llvm35 (should be installed automatically as dependency of clang35)
+- clang35
+- libunwind
+- gettext
+
+Note: LLDB is not yet available in the pkg repository on FreeBSD. The LLDB plugin is currently not being build on FreeBSD. Instructions for this will be added later.
+
+To install the packages you need:
+
+```janhenke@freebsd-frankfurt:~ % sudo pkg install bash cmake clang35 libunwind gettext```
+
+You now have all the required components.
+
+Git Setup
+---------
+
+This guide assumes that you've cloned the coreclr repository into ```~/git/coreclr``` on your FreeBSD machine and the corefx and coreclr repositories into ```D:\git\corefx``` and ```D:\git\coreclr``` on Windows. If your setup is different, you'll need to pay careful attention to the commands you run. In this guide, I'll always show what directory I'm in on both the FreeBSD and Windows machine.
+
+Build the Runtime
+=================
+
+To build the runtime on FreeBSD, run build.sh from the root of the coreclr repository:
+
+```
+janhenke@freebsd-frankfurt:~/git/coreclr % ./build.sh
+```
+
+After the build is completed, there should some files placed in ```bin/Product/FreeBSD.x64.Debug```. The ones we are interested in are:
+
+* ```corerun```: The command line host. This program loads and starts the CoreCLR runtime and passes the managed program you want to run to it.
+* ```libcoreclr.so```: The CoreCLR runtime itself.
+* ```libcoreclrpal.so```: The platform abstraction library for the CoreCLR runtime. This library is temporary and the functionality will be merged back into `libcoreclr.so`
+
+In order to keep everything tidy, let's create a new directory for the runtime and copy the runtime and corerun into it.
+
+```
+janhenke@freebsd-frankfurt:~/git/coreclr % mkdir -p ~/coreclr-demo/runtime
+janhenke@freebsd-frankfurt:~/git/coreclr % cp bin/Product/FreeBSD.x64.Debug/corerun ~/coreclr-demo/runtime
+janhenke@freebsd-frankfurt:~/git/coreclr % cp bin/Product/FreeBSD.x64.Debug/libcoreclr*.so ~/coreclr-demo/runtime
+```
+
+Build the Framework
+===================
+
+We don't _yet_ have support for building managed code on FreeBSD, so you'll need a Windows machine with clones of both the CoreCLR and CoreFX projects.
+
+You will build ```mscorlib.dll``` out of the coreclr repository and the rest of the framework that out of the corefx repository. For mscorlib (from a regular command prompt window) run:
+
+```
+D:\git\coreclr> build.cmd linuxmscorlib
+```
+
+The output is placed in ```bin\obj\Unix.x64.Debug\mscorlib.dll```. You'll want to copy this to the runtime folder on your FreeBSD machine. (e.g. ```~/coreclr-demo/runtime```)
+
+For the rest of the framework, you need to pass some special parameters to build.cmd when building out of the CoreFX repository.
+
+```
+D:\git\corefx> build.cmd /p:OS=Linux /p:SkipTests=true
+```
+
+Note: We are using the Linux build currently, as CoreFX does not yet know about FreeBSD.
+
+It's also possible to add ```/t:rebuild``` to the build.cmd to force it to delete the previously built assemblies.
+
+For the purposes of Hello World, you need to copy over both ```bin\Unix.AnyCPU.Debug\System.Console\System.Console.dll``` and ```bin\Unix.AnyCPU.Debug\System.Diagnostics.Debug\System.Diagnostics.Debug.dll``` into the runtime folder on FreeBSD. (e.g ```~/coreclr-demo/runtime```).
+
+After you've done these steps, the runtime directory on FreeBSD should look like this:
+
+```
+janhenke@freebsd-frankfurt:~/git/coreclr % ls ~/coreclr-demo/runtime/
+System.Console.dll System.Diagnostics.Debug.dll corerun libcoreclr.so libcoreclrpal.so mscorlib.dll
+```
+
+Download Dependencies
+=====================
+
+The rest of the assemblies you need to run are presently just facades that point to mscorlib. We can pull these dependencies down via NuGet (which currently requires Mono).
+
+Create a folder for the packages:
+
+```
+janhenke@freebsd-frankfurt:~/git/coreclr % mkdir ~/coreclr-demo/packages
+janhenke@freebsd-frankfurt:~/git/coreclr % cd ~/coreclr-demo/packages
+```
+
+Install Mono
+------------
+
+If you don't already have Mono installed on your system, use the pkg tool again:
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/packages % sudo pkg install mono
+```
+
+Download the NuGet Client
+-------------------------
+
+Grab NuGet (if you don't have it already)
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/packages % curl -L -O https://nuget.org/nuget.exe
+```
+Download NuGet Packages
+-----------------------
+
+With Mono and NuGet in hand, you can use NuGet to get the required dependencies.
+
+Make a ```packages.config``` file with the following text. These are the required dependencies of this particular app. Different apps will have different dependencies and require a different ```packages.config``` - see [Issue #480](https://github.com/dotnet/coreclr/issues/480).
+
+```
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="System.Console" version="4.0.0-beta-22703" />
+ <package id="System.Diagnostics.Contracts" version="4.0.0-beta-22703" />
+ <package id="System.Diagnostics.Debug" version="4.0.10-beta-22703" />
+ <package id="System.Diagnostics.Tools" version="4.0.0-beta-22703" />
+ <package id="System.Globalization" version="4.0.10-beta-22703" />
+ <package id="System.IO" version="4.0.10-beta-22703" />
+ <package id="System.IO.FileSystem.Primitives" version="4.0.0-beta-22703" />
+ <package id="System.Reflection" version="4.0.10-beta-22703" />
+ <package id="System.Resources.ResourceManager" version="4.0.0-beta-22703" />
+ <package id="System.Runtime" version="4.0.20-beta-22703" />
+ <package id="System.Runtime.Extensions" version="4.0.10-beta-22703" />
+ <package id="System.Runtime.Handles" version="4.0.0-beta-22703" />
+ <package id="System.Runtime.InteropServices" version="4.0.20-beta-22703" />
+ <package id="System.Text.Encoding" version="4.0.10-beta-22703" />
+ <package id="System.Text.Encoding.Extensions" version="4.0.10-beta-22703" />
+ <package id="System.Threading" version="4.0.10-beta-22703" />
+ <package id="System.Threading.Tasks" version="4.0.10-beta-22703" />
+</packages>
+
+```
+
+And restore your packages.config file:
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/packages % mono nuget.exe restore -Source https://www.myget.org/F/dotnet-corefx/ -PackagesDirectory .
+```
+
+NOTE: This assumes you already installed the default CA certs. If you have problems downloading the packages please see [Issue #602](https://github.com/dotnet/coreclr/issues/602#issuecomment-88203778). The command for FreeBSD is:
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/packages % mozroots --import --sync
+```
+
+Finally, you need to copy over the assemblies to the runtime folder. You don't want to copy over System.Console.dll or System.Diagnostics.Debug however, since the version from NuGet is the Windows version. The easiest way to do this is with a little find magic:
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/packages % find . -wholename '*/aspnetcore50/*.dll' -exec cp -n {} ~/coreclr-demo/runtime \;
+```
+
+Compile an App
+==============
+
+Now you need a Hello World application to run. You can write your own, if you'd like. Personally, I'm partial to the one on corefxlab which will draw Tux for us.
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/packages % cd ~/coreclr-demo/runtime
+janhenke@freebsd-frankfurt:~/coreclr-demo/runtime % curl -O https://raw.githubusercontent.com/dotnet/corefxlab/master/demos/CoreClrConsoleApplications/HelloWorld/HelloWorld.cs
+```
+
+Then you just need to build it, with ```mcs```, the Mono C# compiler. FYI: The Roslyn C# compiler will soon be available on FreeBSD. Because you need to compile the app against the .NET Core surface area, you need to pass references to the contract assemblies you restored using NuGet:
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/runtime % mcs /nostdlib /noconfig /r:../packages/System.Console.4.0.0-beta-22703/lib/contract/System.Console.dll /r:../packages/System.Runtime.4.0.20-beta-22703/lib/contract/System.Runtime.dll HelloWorld.cs
+```
+
+Run your App
+============
+
+You're ready to run Hello World! To do that, run corerun, passing the path to the managed exe, plus any arguments. The HelloWorld from corefxlab will print Tux if you pass "linux" as an argument, so:
+
+```
+janhenke@freebsd-frankfurt:~/coreclr-demo/runtime % ./corerun HelloWorld.exe linux
+```
+
+Note: This command is known to hang currently. We are working on it, the progress is tracked in [Issue #801](https://github.com/dotnet/coreclr/issues/801)
+
+Over time, this process will get easier. We will remove the dependency on having to compile managed code on Windows. For example, we are working to get our NuGet packages to include both the Windows and FreeBSD versions of an assembly, so you can simply nuget restore the dependencies.
+
+Pull Requests to enable building CoreFX and mscorlib on FreeBSD via Mono would be very welcome. A sample that builds Hello World on FreeBSD using the correct references but via XBuild or MonoDevelop would also be great! Some of our processes (e.g. the mscorlib build) rely on Windows specific tools, but we want to figure out how to solve these problems for FreeBSD as well. There's still a lot of work ahead, so if you're interested in helping, we're ready for you!
diff --git a/Documentation/get-dotnetcore-windows-dnvm.md b/Documentation/get-dotnetcore-windows-dnvm.md
new file mode 100644
index 0000000000..b9ff97143f
--- /dev/null
+++ b/Documentation/get-dotnetcore-windows-dnvm.md
@@ -0,0 +1,107 @@
+Get .NET Core on Windows with DNVM
+==================================
+
+These instructions will lead you through acquiring .NET Core via the [.NET Version Manager (DNVM)](https://github.com/aspnet/dnvm) and running a "Hello World" demo on Windows. The instructions use a particular set of paths. You'll need to adjust if you want to use a different set.
+
+These instructions are for .NET Core console apps. If you want to try out ASP.NET 5 on top of .NET Core - which is a great idea - check out the [ASP.NET 5 instructions](https://github.com/aspnet/home).
+
+.NET Core is distributed as NuGet packages. You can acquire it via [NuGet restore](get-coreclr-windows-nuget.md) or the .NET Version Manager (these instructions). Alternatively, you can [build from source](windows-instructions.md).
+
+You can see the [CoreCLR myget feed](https://www.myget.org/F/dotnet-core) @ the [dotnet-core gallery](https://www.myget.org/gallery/dotnet-core) page. These packages are not yet published to NuGet.org, but that will change soon.
+
+Installing DNVM
+===============
+
+You need DNVM as a starting point. DNVM enables you to acquire a (or multiple) .NET Execution Environment (DNX). DNVM is simply a script, which doesn't depend on .NET. You can install it via a PowerShell command. You can find alternate DNVM install instructions at the [ASP.NET Home repo](https://github.com/aspnet/home).
+
+ @powershell -NoProfile -ExecutionPolicy unrestricted -Command "&{$Branch='dev';iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/aspnet/Home/dev/dnvminstall.ps1'))}"
+
+You must close your command-prompt and start a new one in order for the user-wide environment variables to take effect.
+
+You can see the currently installed DNX versions with `dnvm list`, which will display an empty set of installed runtimes.
+
+ C:\coreclr-demo>dnvm list
+
+Installing a .NET Core DNX
+==========================
+
+It's easy to install the latest .NET Core-based DNX, using the ```dnvm install``` command.
+
+ C:\coreclr-demo>dnvm install -r coreclr latest
+
+This will install the 32-bit version of .NET Core. If you want the 64-bit version, you can specify processor architecture.
+
+ C:\coreclr-demo>dnvm install -r coreclr -arch x64 latest
+
+You can see the currently installed DNX versions with `dnvm list`.
+
+ C:\coreclr-demo>dnvm list
+
+ Active Version Runtime Architecture Location
+ ------ ------- ------- ------------ --------
+ * 1.0.0-beta5-11596 coreclr x64 C:\Users\rlander\.dnx\runtimes
+ 1.0.0-beta5-11596 coreclr x86 C:\Users\rlander\.dnx\runtimes
+
+You can choose which of these DNXs you want to use with `dnvm use`, with similar arguments.
+
+ C:\coreclr-demo>dnvm use -r coreclr -arch x86 1.0.0-beta5-11596
+ Adding C:\Users\rlander\.dnx\runtimes\dnx-coreclr-win-x86.1.0.0-beta5-11596\bin
+ to process PATH
+
+ C:\coreclr-demo>dnvm list
+
+ Active Version Runtime Architecture Location
+ ------ ------- ------- ------------ --------
+ 1.0.0-beta5-11596 coreclr x64 C:\Users\rlander\.dnx\runtimes
+ * 1.0.0-beta5-11596 coreclr x86 C:\Users\rlander\.dnx\runtimes
+
+Write your App
+==============
+
+You need a Hello World application to run. You can write your own, if you'd like. Here's a very simple one:
+
+```csharp
+using System;
+
+public class Program
+{
+ public static void Main (string[] args)
+ {
+ Console.WriteLine("Hello, Windows");
+ Console.WriteLine("Love from CoreCLR.");
+ }
+}
+```
+
+Some people on the .NET Core team are partial to a demo console app on corefxlab repo which will print a picture for you. Download the [corefxlab demo](https://raw.githubusercontent.com/dotnet/corefxlab/master/demos/CoreClrConsoleApplications/HelloWorld/HelloWorld.cs) to ```C:\coreclr-demo```.
+
+You need a `project.json` that matches your app. Use this one. It will work for both of the apps provided/referenced above. Save the project.json beside your app.
+
+```
+{
+ "version": "1.0.0-*",
+ "dependencies": {
+ },
+ "frameworks" : {
+ "dnx451" : { },
+ "dnxcore50" : {
+ "dependencies": {
+ "System.Console": "4.0.0-beta-*"
+ }
+ }
+ }
+}
+```
+
+Run your App
+============
+
+You need to restore packages for your app, based on your project.json, with `dnu restore`.
+
+ C:\coreclr-demo>dnu restore
+
+You can run your app with the DNX command.
+
+ C:\coreclr-demo>dnx . run
+ Hello, Windows
+ Love from CoreCLR. \ No newline at end of file
diff --git a/Documentation/get-coreclr-windows.md b/Documentation/get-dotnetcore-windows-nuget.md
index 60953a5b25..77ad20370a 100644
--- a/Documentation/get-coreclr-windows.md
+++ b/Documentation/get-dotnetcore-windows-nuget.md
@@ -1,9 +1,9 @@
-Get CoreCLR on Windows
-======================
+Get .NET Core on Windows with NuGet
+===================================
-These instructions will lead you through acquiring CoreCLR and running a "Hello World" demo on Windows. The instructions use a particular set of paths. You'll need to adjust if you want to use a different set.
+These instructions will lead you through acquiring .NET Core via NuGet and running a "Hello World" demo on Windows. The instructions use a particular set of paths. You'll need to adjust if you want to use a different set.
-CoreCLR is distributed as NuGet packages. There is no installer or other distribution mechanism, other than [building from source](windows-instructions.md). You acquire CoreCLR via the normal NuGet restore experience.
+.NET Core is distributed as NuGet packages. You can acquire it via NuGet restore (these instructions) or the [.NET Version Manager](get-coreclr-windows-dnvm.md). Alternatively, you can [build from source](windows-instructions.md).
You can see the [CoreCLR myget feed](https://www.myget.org/F/dotnet-core) @ the [dotnet-core gallery](https://www.myget.org/gallery/dotnet-core) page. These packages are not yet published to NuGet.org, but that will change soon.
diff --git a/Documentation/windows-instructions.md b/Documentation/windows-instructions.md
index 639ac3b854..48a3ab08c7 100644
--- a/Documentation/windows-instructions.md
+++ b/Documentation/windows-instructions.md
@@ -16,7 +16,7 @@ Visual Studio must be installed. Supported versions:
- [Visual Studio Community 2013](http://go.microsoft.com/fwlink/?LinkId=517284) - **Free** for Open Source development!
- [Visual Studio 2013](http://www.visualstudio.com/downloads/download-visual-studio-vs) (Pro, Premium, Ultimate)
-Visual Studio Express is not supported. Visual Studio 2015 isn't supported yet.
+Visual Studio Express is not supported. Visual Studio 2015 isn't supported yet (see [issue #30](https://github.com/dotnet/coreclr/issues/30)).
**Known Issues**
@@ -185,4 +185,4 @@ You're ready to run Hello World! To do that, run corerun, passing the path to th
CoreRun.exe HelloWorld.exe
-Over time, this process will get easier. Thanks for trying out CoreCLR. Feel free to try a more interesting demo. \ No newline at end of file
+Over time, this process will get easier. Thanks for trying out CoreCLR. Feel free to try a more interesting demo.
diff --git a/README.md b/README.md
index a4125a0726..818bbc2a69 100644
--- a/README.md
+++ b/README.md
@@ -6,18 +6,18 @@ The CoreCLR repo contains the complete runtime implementation for [.NET Core](ht
Build Status
------------
-| |Linux |Windows |Mac OS X |
-|---------|:------:|:------:|:-------:|
-|**Debug**|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_debug/)|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_debug/)|[![Build Status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_debug/) |
-|**Release**|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_release/)|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_release/)|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_release/) |
+| |Linux |Windows |Mac OS X |FreeBSD |
+|---------|:------:|:------:|:-------:|:-------:|
+|**Debug**|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_debug/)|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_debug/)|[![Build Status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_debug/) |[![Build Status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_freebsd_debug/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_freebsd_debug/) |
+|**Release**|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_linux_release/)|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_windows_release/)|[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_mac_release/) |[![Build status](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_freebsd_release/badge/icon)](http://dotnet-ci.cloudapp.net/job/dotnet_coreclr_freebsd_release/) |
Get CoreCLR
-----------
-| |Linux |Windows |Mac OS X |
-|---------------------|:------:|:------:|:-------:|
-|Build from **Source**| [Instructions](Documentation/linux-instructions.md) | [Instructions](Documentation/windows-instructions.md) | [Instructions](Documentation/osx-instructions.md) |
-|Get **Binaries** | |[Instructions](Documentation/get-coreclr-windows.md)||
+| |Linux |Windows |Mac OS X |FreeBSD |
+|---------------------|--------|--------|---------|---------|
+|Build from **Source**| [Instructions](Documentation/linux-instructions.md) | [Instructions](Documentation/windows-instructions.md) | [Instructions](Documentation/osx-instructions.md) | [Instructions](Documentation/freebsd-instructions.md) |
+|Get **Binaries** | |[NuGet](Documentation/get-dotnetcore-windows-nuget.md) <br> [DNVM](Documentation/get-dotnetcore-windows-dnvm.md) |||
Chat Room
---------
diff --git a/build.cmd b/build.cmd
index 8f8393cb5c..414186a945 100644
--- a/build.cmd
+++ b/build.cmd
@@ -6,6 +6,10 @@ set __BuildArch=x64
set __BuildType=Debug
set __BuildOS=Windows_NT
+:: Default to VS2013
+set __VSVersion=VS2013
+set __VSProductVersion=120
+
:: Set the various build properties here so that CMake and MSBuild can pick them up
set "__ProjectDir=%~dp0"
:: remove trailing slash
@@ -30,6 +34,9 @@ if /i "%1" == "clean" (set __CleanBuild=1&shift&goto Arg_Loop)
if /i "%1" == "linuxmscorlib" (set __MscorlibOnly=1&set __BuildOS=Linux&shift&goto Arg_Loop)
if /i "%1" == "osxmscorlib" (set __MscorlibOnly=1&set __BuildOS=OSX&shift&goto Arg_Loop)
+if /i "%1" == "vs2013" (set __VSVersion=%1&set __VSProductVersion=120&shift&goto Arg_Loop)
+if /i "%1" == "vs2015" (set __VSVersion=%1&set __VSProductVersion=140&shift&goto Arg_Loop)
+
echo Invalid commandline argument: %1
goto Usage
@@ -79,25 +86,27 @@ goto CheckVS
:CheckVS
:: Check presence of VS
-if defined VS120COMNTOOLS goto CheckVSExistence
+if defined VS%__VSProductVersion%COMNTOOLS goto CheckVSExistence
echo Visual Studio 2013 Community (free) is a pre-requisite to build this repository.
echo See: https://github.com/dotnet/coreclr/wiki/Developer-Guide#prerequisites
goto :eof
:CheckVSExistence
-:: Does VS 2013 really exist?
-if exist "%VS120COMNTOOLS%\..\IDE\devenv.exe" goto CheckMSBuild
+:: Does VS 2013 or VS 2015 really exist?
+if exist "!VS%__VSProductVersion%COMNTOOLS!\..\IDE\devenv.exe" goto CheckMSBuild
echo Visual Studio 2013 Community (free) is a pre-requisite to build this repository.
echo See: https://github.com/dotnet/coreclr/wiki/Developer-Guide#prerequisites
goto :eof
-:CheckMSBuild
+:CheckMSBuild
:: Note: We've disabled node reuse because it causes file locking issues.
:: The issue is that we extend the build with our own targets which
:: means that that rebuilding cannot successfully delete the task
:: assembly.
+if /i "%__VSVersion%" =="vs2015" goto MSBuild14
set _msbuildexe="%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles%\MSBuild\12.0\Bin\MSBuild.exe"
+:MSBuild14
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles%\MSBuild\14.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% echo Error: Could not find MSBuild.exe. Please see https://github.com/dotnet/coreclr/wiki/Developer%%20Guide for build instructions. && exit /b 1
@@ -111,7 +120,7 @@ echo Commencing build of native components for %__BuildOS%.%__BuildArch%.%__Buil
echo.
:: Set the environment for the native build
-call "%VS120COMNTOOLS%\..\..\VC\vcvarsall.bat" x86_amd64
+call "!VS%__VSProductVersion%COMNTOOLS!\..\..\VC\vcvarsall.bat" x86_amd64
if exist "%VSINSTALLDIR%DIA SDK" goto GenVSSolution
echo Error: DIA SDK is missing at "%VSINSTALLDIR%DIA SDK". ^
@@ -127,7 +136,7 @@ goto :eof
:GenVSSolution
:: Regenerate the VS solution
pushd "%__IntermediatesDir%"
-call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%"
+call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectDir%" %__VSVersion%
popd
:BuildComponents
@@ -157,7 +166,7 @@ set Platform=
if defined __MscorlibOnly set __AdditionalMSBuildArgs=/p:BuildNugetPackage=false
:: Set the environment for the managed build
-call "%VS120COMNTOOLS%\VsDevCmd.bat"
+call "!VS%__VSProductVersion%COMNTOOLS!\VsDevCmd.bat"
echo Commencing build of mscorlib for %__BuildOS%.%__BuildArch%.%__BuildType%
echo.
set "__MScorlibBuildLog=%__LogsDir%\MScorlib_%__BuildOS%__%__BuildArch%__%__BuildType%.log"
@@ -202,11 +211,12 @@ goto :eof
:Usage
echo.
echo Usage:
-echo %0 BuildArch BuildType [clean] where:
+echo %0 BuildArch BuildType [clean] [vsversion] where:
echo.
echo BuildArch can be: x64
echo BuildType can be: Debug, Release
echo Clean - optional argument to force a clean build.
+echo VSVersion - optional argument to use VS2013 or VS2015 (default VS2013)
echo linuxmscorlib - Build mscorlib for Linux
echo osxmscorlib - Build mscorlib for OS X
exit /b 1
diff --git a/src/ToolBox/SOS/Strike/eeheap.cpp b/src/ToolBox/SOS/Strike/eeheap.cpp
index 07b8b6de6d..ece84a2830 100644
--- a/src/ToolBox/SOS/Strike/eeheap.cpp
+++ b/src/ToolBox/SOS/Strike/eeheap.cpp
@@ -678,7 +678,7 @@ BOOL GCObjInHeap(TADDR taddrObj, const DacpGcHeapDetails &heap,
#ifndef FEATURE_PAL
// this function updates genUsage to reflect statistics from the range defined by [start, end)
-void GCGenUsageStats(TADDR start, TADDR end, const std::hash_set<TADDR> &liveObjs,
+void GCGenUsageStats(TADDR start, TADDR end, const std::unordered_set<TADDR> &liveObjs,
const DacpGcHeapDetails &heap, BOOL bLarge, const AllocInfo *pAllocInfo, GenUsageStat *genUsage)
{
// if this is an empty segment or generation return
@@ -787,7 +787,7 @@ BOOL GCHeapUsageStats(const DacpGcHeapDetails& heap, BOOL bIncUnreachable, HeapU
#ifndef FEATURE_PAL
// this will create the bitmap of rooted objects only if bIncUnreachable is true
GCRootImpl gcroot;
- const std::hash_set<TADDR> &liveObjs = gcroot.GetLiveObjects();
+ const std::unordered_set<TADDR> &liveObjs = gcroot.GetLiveObjects();
// 1a. enumerate all non-ephemeral segments
while (taddrSeg != (TADDR)heap.generation_table[0].start_segment)
diff --git a/src/ToolBox/SOS/Strike/gcroot.cpp b/src/ToolBox/SOS/Strike/gcroot.cpp
index d135883549..573eda4ecc 100644
--- a/src/ToolBox/SOS/Strike/gcroot.cpp
+++ b/src/ToolBox/SOS/Strike/gcroot.cpp
@@ -23,7 +23,7 @@
* the GCDesc which is required to walk the object's references.
* 3. Use O(1) data structures for anything perf-critical. Almost all of the data structures we use to
* keep track of data have very fast lookups. For example, to keep track of the objects we've considered
- * we use a hash_set. Similarly to keep track of MethodTable data we use a hash_map to track the
+ * we use a unordered_set. Similarly to keep track of MethodTable data we use a unordered_map to track the
* mt -> mtinfo mapping.
*/
#include "sos.h"
@@ -129,13 +129,13 @@ void GCRootImpl::ClearAll()
ClearNodes();
{
- std::hash_map<TADDR, MTInfo*>::iterator itr;
+ std::unordered_map<TADDR, MTInfo*>::iterator itr;
for (itr = mMTs.begin(); itr != mMTs.end(); ++itr)
delete itr->second;
}
{
- std::hash_map<TADDR, RootNode*>::iterator itr;
+ std::unordered_map<TADDR, RootNode*>::iterator itr;
for (itr = mTargets.begin(); itr != mTargets.end(); ++itr)
delete itr->second;
}
@@ -193,7 +193,7 @@ void GCRootImpl::DeleteNode(RootNode *node)
mRootNewList.push_back(node);
}
-void GCRootImpl::GetDependentHandleMap(std::hash_map<TADDR, std::list<TADDR>> &map)
+void GCRootImpl::GetDependentHandleMap(std::unordered_map<TADDR, std::list<TADDR>> &map)
{
unsigned int type = HNDTYPE_DEPENDENT;
ToRelease<ISOSHandleEnum> handles;
@@ -340,7 +340,7 @@ void GCRootImpl::ObjSize()
}
-const std::hash_set<TADDR> &GCRootImpl::GetLiveObjects(bool excludeFQ)
+const std::unordered_set<TADDR> &GCRootImpl::GetLiveObjects(bool excludeFQ)
{
ClearAll();
GetDependentHandleMap(mDependentHandleMap);
@@ -842,7 +842,7 @@ GCRootImpl::RootNode *GCRootImpl::FilterRoots(RootNode *&list)
// We don't check for Control-C in this loop to avoid inconsistent data.
RootNode *curr_next = curr->Next;
- std::hash_map<TADDR, RootNode *>::iterator targetItr = mTargets.find(curr->Object);
+ std::unordered_map<TADDR, RootNode *>::iterator targetItr = mTargets.find(curr->Object);
if (targetItr != mTargets.end())
{
// We found the object we are looking for (or an object which points to it)!
@@ -881,7 +881,7 @@ GCRootImpl::RootNode *GCRootImpl::FilterRoots(RootNode *&list)
GCRootImpl::RootNode *GCRootImpl::FindPathToTarget(TADDR root)
{
// Early out. We may have already looked at this object.
- std::hash_map<TADDR, RootNode *>::iterator targetItr = mTargets.find(root);
+ std::unordered_map<TADDR, RootNode *>::iterator targetItr = mTargets.find(root);
if (targetItr != mTargets.end())
return targetItr->second;
else if (mConsidered.find(root) != mConsidered.end())
@@ -1044,7 +1044,7 @@ GCRootImpl::RootNode *GCRootImpl::GetGCRefs(RootNode *path, RootNode *node)
}
// Add edges from dependent handles.
- std::hash_map<TADDR, std::list<TADDR>>::iterator itr = mDependentHandleMap.find(obj);
+ std::unordered_map<TADDR, std::list<TADDR>>::iterator itr = mDependentHandleMap.find(obj);
if (itr != mDependentHandleMap.end())
{
for (std::list<TADDR>::iterator litr = itr->second.begin(); litr != itr->second.end(); ++litr)
@@ -1110,7 +1110,7 @@ GCRootImpl::MTInfo *GCRootImpl::GetMTInfo(TADDR mt)
mt &= ~3;
// Do we already have this MethodTable?
- std::hash_map<TADDR, MTInfo *>::iterator itr = mMTs.find(mt);
+ std::unordered_map<TADDR, MTInfo *>::iterator itr = mMTs.find(mt);
if (itr != mMTs.end())
return itr->second;
@@ -1257,7 +1257,7 @@ UINT FindAllPinnedAndStrong(DWORD_PTR handlearray[], UINT arraySize)
void PrintNotReachableInRange(TADDR rngStart, TADDR rngEnd, BOOL bExcludeReadyForFinalization, HeapStat* hpstat, BOOL bShort)
{
GCRootImpl gcroot;
- const std::hash_set<TADDR> &liveObjs = gcroot.GetLiveObjects(bExcludeReadyForFinalization == TRUE);
+ const std::unordered_set<TADDR> &liveObjs = gcroot.GetLiveObjects(bExcludeReadyForFinalization == TRUE);
LinearReadCache cache(512);
cache.EnsureRangeInCache(rngStart, (unsigned int)(rngEnd-rngStart));
@@ -2203,7 +2203,7 @@ void HeapTraverser::PrintRefs(size_t obj, size_t methodTable, size_t size)
}
#ifndef FEATURE_PAL
- std::hash_map<TADDR, std::list<TADDR>>::iterator itr = mDependentHandleMap.find((TADDR)obj);
+ std::unordered_map<TADDR, std::list<TADDR>>::iterator itr = mDependentHandleMap.find((TADDR)obj);
if (itr != mDependentHandleMap.end())
{
for (std::list<TADDR>::iterator litr = itr->second.begin(); litr != itr->second.end(); ++litr)
diff --git a/src/ToolBox/SOS/Strike/strike.cpp b/src/ToolBox/SOS/Strike/strike.cpp
index 6dfebbe84c..5a175cf7f1 100644
--- a/src/ToolBox/SOS/Strike/strike.cpp
+++ b/src/ToolBox/SOS/Strike/strike.cpp
@@ -4010,7 +4010,7 @@ private:
private:
#if !defined(FEATURE_PAL)
// Windows only
- std::hash_set<TADDR> mLiveness;
+ std::unordered_set<TADDR> mLiveness;
typedef std::list<sos::FragmentationBlock> FragmentationList;
FragmentationList mFrag;
diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp
index 0d5126c854..fb0dd0c689 100644
--- a/src/ToolBox/SOS/Strike/util.cpp
+++ b/src/ToolBox/SOS/Strike/util.cpp
@@ -146,7 +146,7 @@ namespace com_activation
{ return memcmp(&_Key1, &_Key2, sizeof(GUID)) == -1; }
};
- static std::hash_map<GUID, HMODULE, hash_compareGUID> *g_pClsidHmodMap = NULL;
+ static std::unordered_map<GUID, HMODULE, hash_compareGUID> *g_pClsidHmodMap = NULL;
@@ -393,7 +393,7 @@ Error:
* *
* Note: *
* *
-* It uses a hash_map to cache the mapping between a CLSID and the *
+* It uses a unordered_map to cache the mapping between a CLSID and the *
* HMODULE that is successfully used to activate the CLSID from. When *
* SOS is unloaded (in DebugExtensionUninitialize()) we call *
* FreeLibrary() for all cached HMODULEs. *
@@ -411,7 +411,7 @@ HRESULT CreateInstanceFromPath(
if (g_pClsidHmodMap == NULL)
{
- g_pClsidHmodMap = new std::hash_map<GUID, HMODULE, hash_compareGUID>();
+ g_pClsidHmodMap = new std::unordered_map<GUID, HMODULE, hash_compareGUID>();
OnUnloadTask::Register(CleanupClsidHmodMap);
}
diff --git a/src/ToolBox/SOS/Strike/util.h b/src/ToolBox/SOS/Strike/util.h
index 6f88a7b141..a2e1b62028 100644
--- a/src/ToolBox/SOS/Strike/util.h
+++ b/src/ToolBox/SOS/Strike/util.h
@@ -2857,8 +2857,8 @@ private:
//
#ifndef FEATURE_PAL
-#include <hash_map>
-#include <hash_set>
+#include <unordered_map>
+#include <unordered_set>
#include <list>
#endif
@@ -2877,7 +2877,7 @@ private:
LinearReadCache mCache;
#ifndef FEATURE_PAL
- std::hash_map<TADDR, std::list<TADDR>> mDependentHandleMap;
+ std::unordered_map<TADDR, std::list<TADDR>> mDependentHandleMap;
#endif
public:
@@ -3031,7 +3031,7 @@ private:
};
public:
- static void GetDependentHandleMap(std::hash_map<TADDR, std::list<TADDR>> &map);
+ static void GetDependentHandleMap(std::unordered_map<TADDR, std::list<TADDR>> &map);
public:
// Finds all objects which root "target" and prints the path from the root
@@ -3050,7 +3050,7 @@ public:
void ObjSize();
// Returns the set of all live objects in the process.
- const std::hash_set<TADDR> &GetLiveObjects(bool excludeFQ = false);
+ const std::unordered_set<TADDR> &GetLiveObjects(bool excludeFQ = false);
// See !FindRoots.
int FindRoots(int gen, TADDR target);
@@ -3108,12 +3108,12 @@ private:
std::list<RootNode*> mCleanupList; // A list of RootNode's we've newed up. This is only used to delete all of them later.
std::list<RootNode*> mRootNewList; // A list of unused RootNodes that are free to use instead of having to "new" up more.
- std::hash_map<TADDR, MTInfo*> mMTs; // The MethodTable cache which maps from MT -> MethodTable data (size, gcdesc, string typename)
- std::hash_map<TADDR, RootNode*> mTargets; // The objects that we are searching for.
- std::hash_set<TADDR> mConsidered; // A hashtable of objects we've already visited.
- std::hash_map<TADDR, size_t> mSizes; // A mapping from object address to total size of data the object roots.
+ std::unordered_map<TADDR, MTInfo*> mMTs; // The MethodTable cache which maps from MT -> MethodTable data (size, gcdesc, string typename)
+ std::unordered_map<TADDR, RootNode*> mTargets; // The objects that we are searching for.
+ std::unordered_set<TADDR> mConsidered; // A hashtable of objects we've already visited.
+ std::unordered_map<TADDR, size_t> mSizes; // A mapping from object address to total size of data the object roots.
- std::hash_map<TADDR, std::list<TADDR>> mDependentHandleMap;
+ std::unordered_map<TADDR, std::list<TADDR>> mDependentHandleMap;
LinearReadCache mCache; // A linear cache which stops us from having to read from the target process more than 1-2 times per object.
};
diff --git a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
index 6448bc6734..ee781a4d2e 100644
--- a/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
+++ b/src/ToolBox/SOS/lldbplugin/CMakeLists.txt
@@ -59,7 +59,9 @@ include_directories(${CLR_DIR}/src/inc)
set(SOURCES
sosplugin.cpp
soscommand.cpp
+ coreruncommand.cpp
debugclient.cpp
+ ${CLR_DIR}/src/coreclr/hosts/unixcorerun/corerun.cpp
)
add_library(sosplugin SHARED ${SOURCES})
diff --git a/src/ToolBox/SOS/lldbplugin/coreruncommand.cpp b/src/ToolBox/SOS/lldbplugin/coreruncommand.cpp
new file mode 100644
index 0000000000..a047488a0b
--- /dev/null
+++ b/src/ToolBox/SOS/lldbplugin/coreruncommand.cpp
@@ -0,0 +1,48 @@
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+
+#include "sosplugin.h"
+#include <dlfcn.h>
+#include <string>
+
+extern int corerun(const int argc, const char* argv[]);
+
+class corerunCommand : public lldb::SBCommandPluginInterface
+{
+public:
+ corerunCommand()
+ {
+ }
+
+ virtual bool
+ DoExecute (lldb::SBDebugger debugger,
+ char** arguments,
+ lldb::SBCommandReturnObject &result)
+ {
+ if (arguments)
+ {
+ int argc = 0;
+ char **argv = arguments;
+ for (const char* arg = *arguments; arg; arg = *(++arguments))
+ {
+ ++argc;
+ }
+ int exitcode = corerun((const int)argc, (const char**)argv);
+ if (exitcode != 0)
+ {
+ result.SetError("corerun failed");
+ }
+ }
+ return result.Succeeded();
+ }
+};
+
+bool
+corerunCommandInitialize(lldb::SBDebugger debugger)
+{
+ lldb::SBCommandInterpreter interpreter = debugger.GetCommandInterpreter();
+ interpreter.AddCommand("corerun", new corerunCommand(), "run a managed app inside the debugger");
+ return true;
+}
diff --git a/src/ToolBox/SOS/lldbplugin/debugclient.cpp b/src/ToolBox/SOS/lldbplugin/debugclient.cpp
index d6a77f6a2e..4d595a4931 100644
--- a/src/ToolBox/SOS/lldbplugin/debugclient.cpp
+++ b/src/ToolBox/SOS/lldbplugin/debugclient.cpp
@@ -3,6 +3,8 @@
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
+#include <cstdarg>
+#include <cstdlib>
#include "sosplugin.h"
#include <string.h>
#include <dbgtargetcontext.h>
diff --git a/src/ToolBox/SOS/lldbplugin/sosplugin.cpp b/src/ToolBox/SOS/lldbplugin/sosplugin.cpp
index 90a009277b..a6111b6186 100644
--- a/src/ToolBox/SOS/lldbplugin/sosplugin.cpp
+++ b/src/ToolBox/SOS/lldbplugin/sosplugin.cpp
@@ -12,5 +12,7 @@ namespace lldb {
bool
lldb::PluginInitialize (lldb::SBDebugger debugger)
{
- return sosCommandInitialize(debugger);
+ corerunCommandInitialize(debugger);
+ sosCommandInitialize(debugger);
+ return true;
} \ No newline at end of file
diff --git a/src/ToolBox/SOS/lldbplugin/sosplugin.h b/src/ToolBox/SOS/lldbplugin/sosplugin.h
index 993d7227b6..e031660f7f 100644
--- a/src/ToolBox/SOS/lldbplugin/sosplugin.h
+++ b/src/ToolBox/SOS/lldbplugin/sosplugin.h
@@ -11,4 +11,7 @@
typedef HRESULT (*CommandFunc)(PDEBUG_CLIENT client, const char *args);
bool
-sosCommandInitialize(lldb::SBDebugger debugger); \ No newline at end of file
+sosCommandInitialize(lldb::SBDebugger debugger);
+
+bool
+corerunCommandInitialize(lldb::SBDebugger debugger); \ No newline at end of file
diff --git a/src/coreclr/hosts/unixcorerun/CMakeLists.txt b/src/coreclr/hosts/unixcorerun/CMakeLists.txt
index 6ad4102d3e..e82f0e2d97 100644
--- a/src/coreclr/hosts/unixcorerun/CMakeLists.txt
+++ b/src/coreclr/hosts/unixcorerun/CMakeLists.txt
@@ -22,6 +22,13 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
)
endif(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+# FreeBSD requires pthread to be loaded by the executable process
+if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ target_link_libraries(corerun
+ pthread
+ )
+endif(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+
add_dependencies(corerun
coreclr
)
diff --git a/src/coreclr/hosts/unixcorerun/corerun.cpp b/src/coreclr/hosts/unixcorerun/corerun.cpp
index 5f7bb6525b..8308e39f6b 100644
--- a/src/coreclr/hosts/unixcorerun/corerun.cpp
+++ b/src/coreclr/hosts/unixcorerun/corerun.cpp
@@ -321,7 +321,7 @@ int ExecuteManagedAssembly(
return -1;
}
- void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_GLOBAL);
+ void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL);
if (coreclrLib != nullptr)
{
ExecuteAssemblyFunction executeAssembly = (ExecuteAssemblyFunction)dlsym(coreclrLib, "ExecuteAssembly");
@@ -402,7 +402,7 @@ int ExecuteManagedAssembly(
return exitCode;
}
-int main(const int argc, const char* argv[])
+int corerun(const int argc, const char* argv[])
{
const char* clrFilesPath;
const char* managedAssemblyPath;
@@ -484,3 +484,8 @@ int main(const int argc, const char* argv[])
managedAssemblyArgv);
return exitCode;
}
+
+int main(const int argc, const char* argv[])
+{
+ return corerun(argc, argv);
+}
diff --git a/src/debug/daccess/dacimpl.h b/src/debug/daccess/dacimpl.h
index 0499407a74..59839b7987 100644
--- a/src/debug/daccess/dacimpl.h
+++ b/src/debug/daccess/dacimpl.h
@@ -18,7 +18,7 @@
#if defined(_TARGET_ARM_) || defined(FEATURE_CORESYSTEM) // @ARMTODO: STL breaks the build with current VC headers
//---------------------------------------------------------------------------------------
// Setting DAC_HASHTABLE tells the DAC to use the hand rolled hashtable for
-// storing code:DAC_INSTANCE . Otherwise, the DAC uses the STL hash_map to.
+// storing code:DAC_INSTANCE . Otherwise, the DAC uses the STL unordered_map to.
#define DAC_HASHTABLE
#endif // _TARGET_ARM_|| FEATURE_CORESYSTEM
@@ -26,7 +26,7 @@
#ifndef DAC_HASHTABLE
#pragma push_macro("return")
#undef return
-#include <hash_map>
+#include <unordered_map>
#pragma pop_macro("return")
#endif //DAC_HASHTABLE
extern CRITICAL_SECTION g_dacCritSec;
@@ -784,7 +784,7 @@ private:
HashInstanceKeyBlock* m_hash[DAC_INSTANCE_HASH_SIZE];
#else //DAC_HASHTABLE
- // We're going to use the STL hash_map for our instance hash.
+ // We're going to use the STL unordered_map for our instance hash.
// This has the benefit of scaling to different workloads appropriately (as opposed to having a
// fixed number of buckets).
@@ -829,7 +829,7 @@ private:
#endif
};
- typedef stdext::hash_map<TADDR, DAC_INSTANCE*, DacHashCompare > DacInstanceHash;
+ typedef stdext::unordered_map<TADDR, DAC_INSTANCE*, DacHashCompare > DacInstanceHash;
typedef DacInstanceHash::value_type DacInstanceHashValue;
typedef DacInstanceHash::iterator DacInstanceHashIterator;
DacInstanceHash m_hash;
diff --git a/src/mscorlib/src/System/IO/FileSecurityState.cs b/src/mscorlib/src/System/IO/FileSecurityState.cs
index 00133e5657..872cf4f815 100644
--- a/src/mscorlib/src/System/IO/FileSecurityState.cs
+++ b/src/mscorlib/src/System/IO/FileSecurityState.cs
@@ -25,7 +25,9 @@ namespace System.IO
[System.Runtime.CompilerServices.FriendAccessAllowed]
internal class FileSecurityState : SecurityState
{
+#if !PLATFORM_UNIX
private static readonly char[] m_illegalCharacters = { '?', '*' };
+#endif // !PLATFORM_UNIX
private FileSecurityStateAccess m_access;
private String m_userPath;
@@ -125,8 +127,10 @@ namespace System.IO
System.IO.Path.CheckInvalidPathChars(path);
+#if !PLATFORM_UNIX
if (path.IndexOfAny( m_illegalCharacters ) != -1)
throw new ArgumentException( Environment.GetResourceString( "Argument_InvalidPathChars" ) );
+#endif // !PLATFORM_UNIX
}
}
}
diff --git a/src/pal/src/exception/machexception.cpp b/src/pal/src/exception/machexception.cpp
index 7d31f76e4f..d4350c7489 100644
--- a/src/pal/src/exception/machexception.cpp
+++ b/src/pal/src/exception/machexception.cpp
@@ -902,40 +902,7 @@ catch_exception_raise(
void **FramePointer = (void **)ThreadState.esp;
- // ThreadState.eip points to the instruction that caused the fault.
- // In the frame we're constructing, we'll pretend PAL_DispatchExceptionWrapper
- // was called by eip+1 instead of eip to work around a quirk in the
- // stack unwinding logic of the gcc runtime.
- //
- // The quirk is the following. The stack unwinder of the gcc runtime
- // has been designed for unwinding stack frames created by ordinary
- // function calls, so it expects that every return address on the
- // stack points to an instruction following a call instruction. If
- // the target of a given call is a function declared to never return,
- // gcc can generate code where this call is the very last instruction
- // in a function, in which case the return address points to the first
- // instruction of the function that happens to be laid out immediately
- // after the calling function in the binary. To ensure it gets the
- // exception handling table for the right function, the stack unwinder
- // therefore always subtracts one from any return address. (Note that
- // gdb isn't as smart in this case and actually shows the wrong symbol
- // in a backtrace!) Similarly, gcc's personality routine uses eip-1
- // when looking up which try block we're in, since the call could have
- // been the last instruction in the try block.
- //
- // This logic breaks down for the stack frame we are constructing here
- // if our faulting instruction is the first instruction in a try block,
- // since eip-1 would point outside the range of instructions that make
- // up said block. We fix this by storing eip+1 as the return address.
- //
- // Do we expect this to cause any problems to other code? No - since
- // we never actually return from PAL_DispatchException, this value
- // should only ever be examined by the exception unwinder and gcc's
- // personality routine. At worst, this can cause some confusion to
- // developers looking at stack traces produced by tools such as gdb
- // and CrashReporter, who may see an eip that points in the middle of
- // an instruction.
- *--FramePointer = (void *)((ULONG_PTR)ThreadState.eip + 1);
+ *--FramePointer = (void *)((ULONG_PTR)ThreadState.eip);
// Construct a stack frame for a pretend activation of the function
// PAL_DispatchExceptionWrapper that serves only to make the stack
@@ -983,40 +950,7 @@ catch_exception_raise(
void **FramePointer = (void **)ThreadState.__rsp;
- // ThreadState.eip points to the instruction that caused the fault.
- // In the frame we're constructing, we'll pretend PAL_DispatchExceptionWrapper
- // was called by eip+1 instead of eip to work around a quirk in the
- // stack unwinding logic of the gcc runtime.
- //
- // The quirk is the following. The stack unwinder of the gcc runtime
- // has been designed for unwinding stack frames created by ordinary
- // function calls, so it expects that every return address on the
- // stack points to an instruction following a call instruction. If
- // the target of a given call is a function declared to never return,
- // gcc can generate code where this call is the very last instruction
- // in a function, in which case the return address points to the first
- // instruction of the function that happens to be laid out immediately
- // after the calling function in the binary. To ensure it gets the
- // exception handling table for the right function, the stack unwinder
- // therefore always subtracts one from any return address. (Note that
- // gdb isn't as smart in this case and actually shows the wrong symbol
- // in a backtrace!) Similarly, gcc's personality routine uses eip-1
- // when looking up which try block we're in, since the call could have
- // been the last instruction in the try block.
- //
- // This logic breaks down for the stack frame we are constructing here
- // if our faulting instruction is the first instruction in a try block,
- // since eip-1 would point outside the range of instructions that make
- // up said block. We fix this by storing eip+1 as the return address.
- //
- // Do we expect this to cause any problems to other code? No - since
- // we never actually return from PAL_DispatchException, this value
- // should only ever be examined by the exception unwinder and gcc's
- // personality routine. At worst, this can cause some confusion to
- // developers looking at stack traces produced by tools such as gdb
- // and CrashReporter, who may see an eip that points in the middle of
- // an instruction.
- *--FramePointer = (void *)((ULONG_PTR)ThreadState.__rip + 1);
+ *--FramePointer = (void *)((ULONG_PTR)ThreadState.__rip);
// Construct a stack frame for a pretend activation of the function
// PAL_DispatchExceptionWrapper that serves only to make the stack
diff --git a/src/pal/src/exception/seh.cpp b/src/pal/src/exception/seh.cpp
index 4091914603..ab48ccafe2 100644
--- a/src/pal/src/exception/seh.cpp
+++ b/src/pal/src/exception/seh.cpp
@@ -100,12 +100,12 @@ SEHInitialize (CPalThread *pthrCurrent, DWORD flags)
if (!SEHInitializeConsole())
{
ERROR("SEHInitializeConsole failed!\n");
- SEHCleanup(flags);
+ SEHCleanup();
goto SEHInitializeExit;
}
#if !HAVE_MACH_EXCEPTIONS
- SEHInitializeSignals(flags);
+ SEHInitializeSignals();
if (flags & PAL_INITIALIZE_SIGNAL_THREAD)
{
@@ -113,7 +113,7 @@ SEHInitialize (CPalThread *pthrCurrent, DWORD flags)
if (NO_ERROR != palError)
{
ERROR("StartExternalSignalHandlerThread returned %d\n", palError);
- SEHCleanup(flags);
+ SEHCleanup();
goto SEHInitializeExit;
}
}
@@ -131,20 +131,20 @@ Function :
Undo work done by SEHInitialize
Parameters :
- PAL initialize flags
+ None
(no return value)
--*/
VOID
-SEHCleanup(DWORD flags)
+SEHCleanup()
{
TRACE("Cleaning up SEH\n");
#if HAVE_MACH_EXCEPTIONS
SEHCleanupExceptionPort();
#else
- SEHCleanupSignals(flags);
+ SEHCleanupSignals();
#endif
}
@@ -179,9 +179,8 @@ Parameters:
PEXCEPTION_POINTERS pointers
Return value:
- Does not return
+ Returns only if the exception is unhandled
--*/
-PAL_NORETURN
VOID
SEHProcessException(PEXCEPTION_POINTERS pointers)
{
@@ -197,9 +196,7 @@ SEHProcessException(PEXCEPTION_POINTERS pointers)
throw exception;
}
- ASSERT("Unhandled hardware exception %08x\n", pointers->ExceptionRecord->ExceptionCode);
-
- ExitProcess(pointers->ExceptionRecord->ExceptionCode);
+ TRACE("Unhandled hardware exception %08x\n", pointers->ExceptionRecord->ExceptionCode);
}
/*++
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index 8e5f52825c..0496362de1 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -56,43 +56,36 @@ typedef void *siginfo_t;
#endif /* !HAVE_SIGINFO_T */
typedef void (*SIGFUNC)(int, siginfo_t *, void *);
-/* Static variables ***********************************************************/
-static LONG fatal_signal_received;
-
/* internal function declarations *********************************************/
-static void sigint_handler(int code, siginfo_t *siginfo, void *context);
-static void sigquit_handler(int code, siginfo_t *siginfo, void *context);
static void sigill_handler(int code, siginfo_t *siginfo, void *context);
static void sigfpe_handler(int code, siginfo_t *siginfo, void *context);
static void sigsegv_handler(int code, siginfo_t *siginfo, void *context);
static void sigtrap_handler(int code, siginfo_t *siginfo, void *context);
static void sigbus_handler(int code, siginfo_t *siginfo, void *context);
-static void fatal_signal_handler(int code, siginfo_t *siginfo, void *context);
+#if USE_SIGNALS_FOR_THREAD_SUSPENSION
+void CorUnix::suspend_handler(int code, siginfo_t *siginfo, void *context);
+void CorUnix::resume_handler(int code, siginfo_t *siginfo, void *context);
+#endif // USE_SIGNALS_FOR_THREAD_SUSPENSION
+
static void common_signal_handler(PEXCEPTION_POINTERS pointers, int code,
native_context_t *ucontext);
-void handle_signal(int signal_id, SIGFUNC sigfunc);
-inline void check_pal_initialize(int signal_id);
+static void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction);
+static void restore_signal(int signal_id, struct sigaction *previousAction);
+inline void check_pal_initialize(int signal_id, struct sigaction *previousAction);
-#if HAVE__THREAD_SYS_SIGRETURN
-int _thread_sys_sigreturn(native_context_t *);
-#endif
+/* internal data declarations *********************************************/
-#if USE_SIGNALS_FOR_THREAD_SUSPENSION
-void CorUnix::suspend_handler(int code, siginfo_t *siginfo, void *context)
-{
- check_pal_initialize(code);
- CPalThread *pThread = InternalGetCurrentThread();
- pThread->suspensionInfo.HandleSuspendSignal(pThread);
-}
+struct sigaction g_previous_sigill;
+struct sigaction g_previous_sigtrap;
+struct sigaction g_previous_sigfpe;
+struct sigaction g_previous_sigbus;
+struct sigaction g_previous_sigsegv;
-void CorUnix::resume_handler(int code, siginfo_t *siginfo, void *context)
-{
- check_pal_initialize(code);
- CPalThread *pThread = InternalGetCurrentThread();
- pThread->suspensionInfo.HandleResumeSignal();
-}
+#if USE_SIGNALS_FOR_THREAD_SUSPENSION
+struct sigaction g_previous_sigusr1;
+struct sigaction g_previous_sigusr2;
#endif // USE_SIGNALS_FOR_THREAD_SUSPENSION
/* public function definitions ************************************************/
@@ -104,16 +97,14 @@ Function :
Set-up signal handlers to catch signals and translate them to exceptions
Parameters :
- PAL initialize flags
+ None
(no return value)
--*/
-void SEHInitializeSignals(DWORD flags)
+void SEHInitializeSignals()
{
TRACE("Initializing signal handlers\n");
- fatal_signal_received = 0;
-
/* we call handle signal for every possible signal, even
if we don't provide a signal handler.
@@ -127,54 +118,25 @@ void SEHInitializeSignals(DWORD flags)
see sigaction man page for more details
*/
- handle_signal(SIGILL, sigill_handler);
- handle_signal(SIGTRAP, sigtrap_handler);
- handle_signal(SIGFPE, sigfpe_handler);
- handle_signal(SIGBUS, sigbus_handler);
- handle_signal(SIGSEGV, sigsegv_handler);
+ handle_signal(SIGILL, sigill_handler, &g_previous_sigill);
+ handle_signal(SIGTRAP, sigtrap_handler, &g_previous_sigtrap);
+ handle_signal(SIGFPE, sigfpe_handler, &g_previous_sigfpe);
+ handle_signal(SIGBUS, sigbus_handler, &g_previous_sigbus);
+ handle_signal(SIGSEGV, sigsegv_handler, &g_previous_sigsegv);
#if USE_SIGNALS_FOR_THREAD_SUSPENSION
- handle_signal(SIGUSR1, suspend_handler);
- handle_signal(SIGUSR2, resume_handler);
+ handle_signal(SIGUSR1, suspend_handler, &g_previous_sigusr1);
+ handle_signal(SIGUSR2, resume_handler, &g_previous_sigusr2);
#endif
- if (flags & PAL_INITIALIZE_ALL_SIGNALS)
- {
- handle_signal(SIGHUP, fatal_signal_handler);
- handle_signal(SIGINT, sigint_handler);
- handle_signal(SIGQUIT, sigquit_handler);
- handle_signal(SIGABRT, fatal_signal_handler);
-#ifdef SIGEMT
- handle_signal(SIGEMT, fatal_signal_handler);
-#endif // SIGEMT
- handle_signal(SIGSYS, fatal_signal_handler);
- handle_signal(SIGALRM, fatal_signal_handler);
- handle_signal(SIGTERM, fatal_signal_handler);
- handle_signal(SIGURG, NULL);
- handle_signal(SIGTSTP, NULL);
- handle_signal(SIGCONT, NULL);
- handle_signal(SIGCHLD, NULL);
- handle_signal(SIGTTIN, NULL);
- handle_signal(SIGTTOU, NULL);
- handle_signal(SIGIO, NULL);
- handle_signal(SIGXCPU, fatal_signal_handler);
- handle_signal(SIGXFSZ, fatal_signal_handler);
- handle_signal(SIGVTALRM, fatal_signal_handler);
- handle_signal(SIGPROF, fatal_signal_handler);
- handle_signal(SIGWINCH, NULL);
-#ifdef SIGINFO
- handle_signal(SIGINFO, NULL);
-#endif // SIGINFO
-
- /* The default action for SIGPIPE is process termination.
- Since SIGPIPE can be signaled when trying to write on a socket for which
- the connection has been dropped, we need to tell the system we want
- to ignore this signal.
-
- Instead of terminating the process, the system call which would had
- issued a SIGPIPE will, instead, report an error and set errno to EPIPE.
- */
- signal(SIGPIPE, SIG_IGN);
- }
+ /* The default action for SIGPIPE is process termination.
+ Since SIGPIPE can be signaled when trying to write on a socket for which
+ the connection has been dropped, we need to tell the system we want
+ to ignore this signal.
+
+ Instead of terminating the process, the system call which would had
+ issued a SIGPIPE will, instead, report an error and set errno to EPIPE.
+ */
+ signal(SIGPIPE, SIG_IGN);
}
/*++
@@ -184,7 +146,7 @@ Function :
Restore default signal handlers
Parameters :
- PAL initialize flags
+ None
(no return value)
@@ -193,80 +155,55 @@ reason for this function is that during PAL_Terminate, we reach a point where
SEH isn't possible anymore (handle manager is off, etc). Past that point,
we can't avoid crashing on a signal
--*/
-void SEHCleanupSignals (DWORD flags)
+void SEHCleanupSignals()
{
TRACE("Restoring default signal handlers\n");
- handle_signal(SIGILL, NULL);
- handle_signal(SIGTRAP, NULL);
- handle_signal(SIGFPE, NULL);
- handle_signal(SIGBUS, NULL);
- handle_signal(SIGSEGV, NULL);
-
- if (flags & PAL_INITIALIZE_ALL_SIGNALS)
- {
- handle_signal(SIGHUP, NULL);
- handle_signal(SIGINT, NULL);
- handle_signal(SIGQUIT, NULL);
- handle_signal(SIGABRT, NULL);
-#ifdef SIGEMT
- handle_signal(SIGEMT, NULL);
-#endif // SIGEMT
- handle_signal(SIGSYS, NULL);
- handle_signal(SIGALRM, NULL);
- handle_signal(SIGTERM, NULL);
- handle_signal(SIGXCPU, NULL);
- handle_signal(SIGXFSZ, NULL);
- handle_signal(SIGVTALRM, NULL);
- handle_signal(SIGPROF, NULL);
- handle_signal(SIGPIPE, NULL);
- /* Do not remove handlers for SIGUSR1 and SIGUSR2. They must remain so threads can be suspended
+ /* Do not remove handlers for SIGUSR1 and SIGUSR2. They must remain so threads can be suspended
during cleanup after this function has been called. */
- }
+ restore_signal(SIGILL, &g_previous_sigill);
+ restore_signal(SIGTRAP, &g_previous_sigtrap);
+ restore_signal(SIGFPE, &g_previous_sigfpe);
+ restore_signal(SIGBUS, &g_previous_sigbus);
+ restore_signal(SIGSEGV, &g_previous_sigsegv);
}
-
/* internal function definitions **********************************************/
-/*++
-Function :
- sigint_handler
+#if USE_SIGNALS_FOR_THREAD_SUSPENSION
- This signal is now handled by the PAL signal handling thread : see seh.cpp
- The SIGINT signal (CONTROL_C_EXIT exception) is intercepted by the signal handling thread,
- which creates a new thread, that calls SEHHandleControlEvent, to handle the SIGINT.
+void CorUnix::suspend_handler(int code, siginfo_t *siginfo, void *context)
+{
+ check_pal_initialize(code, &g_previous_sigusr1);
-Parameters :
- POSIX signal handler parameter list ("man sigaction" for details)
+ CPalThread *pThread = InternalGetCurrentThread();
+ pThread->suspensionInfo.HandleSuspendSignal(pThread);
- (no return value)
---*/
-static void sigint_handler(int code, siginfo_t *siginfo, void *context)
-{
- check_pal_initialize(code);
- ASSERT("Should not reach sigint_handler\n");
+ TRACE("SIGUSR1 signal was unhandled; chaining to previous sigaction\n");
+
+ if (g_previous_sigusr1.sa_sigaction != NULL)
+ {
+ g_previous_sigusr1.sa_sigaction(code, siginfo, context);
+ }
}
-/*++
-Function :
- sigquit_handler
-
- This signal is now handled by the PAL signal handling thread : see seh.cpp
- The SIGQUIT signal is intercepted by the signal handling thread,
- which create a new thread, that calls SEHHandleControlEvent, to handle the SIGQUIT.
+void CorUnix::resume_handler(int code, siginfo_t *siginfo, void *context)
+{
+ check_pal_initialize(code, &g_previous_sigusr2);
-Parameters :
- POSIX signal handler parameter list ("man sigaction" for details)
+ CPalThread *pThread = InternalGetCurrentThread();
+ pThread->suspensionInfo.HandleResumeSignal();
- (no return value)
---*/
-static void sigquit_handler(int code, siginfo_t *siginfo, void *context)
-{
- check_pal_initialize(code);
- ASSERT("Should not reach sigquit_handler\n");
+ TRACE("SIGUSR2 signal was unhandled; chaining to previous sigaction\n");
+ if (g_previous_sigusr2.sa_sigaction != NULL)
+ {
+ g_previous_sigusr2.sa_sigaction(code, siginfo, context);
+ }
}
+#endif // USE_SIGNALS_FOR_THREAD_SUSPENSION
+
/*++
Function :
sigill_handler
@@ -280,7 +217,8 @@ Parameters :
--*/
static void sigill_handler(int code, siginfo_t *siginfo, void *context)
{
- check_pal_initialize(code);
+ check_pal_initialize(code, &g_previous_sigill);
+
EXCEPTION_RECORD record;
EXCEPTION_POINTERS pointers;
native_context_t *ucontext;
@@ -297,7 +235,12 @@ static void sigill_handler(int code, siginfo_t *siginfo, void *context)
common_signal_handler(&pointers, code, ucontext);
- TRACE("SIGILL Signal was handled; continuing execution.\n");
+ TRACE("SIGILL signal was unhandled; chaining to previous sigaction\n");
+
+ if (g_previous_sigill.sa_sigaction != NULL)
+ {
+ g_previous_sigill.sa_sigaction(code, siginfo, context);
+ }
}
/*++
@@ -313,7 +256,8 @@ Parameters :
--*/
static void sigfpe_handler(int code, siginfo_t *siginfo, void *context)
{
- check_pal_initialize(code);
+ check_pal_initialize(code, &g_previous_sigfpe);
+
EXCEPTION_RECORD record;
EXCEPTION_POINTERS pointers;
native_context_t *ucontext;
@@ -330,7 +274,12 @@ static void sigfpe_handler(int code, siginfo_t *siginfo, void *context)
common_signal_handler(&pointers, code, ucontext);
- TRACE("SIGFPE Signal was handled; continuing execution.\n");
+ TRACE("SIGFPE signal was unhandled; chaining to previous sigaction\n");
+
+ if (g_previous_sigfpe.sa_sigaction != NULL)
+ {
+ g_previous_sigfpe.sa_sigaction(code, siginfo, context);
+ }
}
/*++
@@ -346,7 +295,8 @@ Parameters :
--*/
static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
{
- check_pal_initialize(code);
+ check_pal_initialize(code, &g_previous_sigsegv);
+
EXCEPTION_RECORD record;
EXCEPTION_POINTERS pointers;
native_context_t *ucontext;
@@ -371,7 +321,12 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
common_signal_handler(&pointers, code, ucontext);
- TRACE("SIGSEGV Signal was handled; continuing execution.\n");
+ TRACE("SIGSEGV signal was unhandled; chaining to previous sigaction\n");
+
+ if (g_previous_sigsegv.sa_sigaction != NULL)
+ {
+ g_previous_sigsegv.sa_sigaction(code, siginfo, context);
+ }
}
/*++
@@ -387,7 +342,8 @@ Parameters :
--*/
static void sigtrap_handler(int code, siginfo_t *siginfo, void *context)
{
- check_pal_initialize(code);
+ check_pal_initialize(code, &g_previous_sigtrap);
+
EXCEPTION_RECORD record;
EXCEPTION_POINTERS pointers;
native_context_t *ucontext;
@@ -404,7 +360,12 @@ static void sigtrap_handler(int code, siginfo_t *siginfo, void *context)
common_signal_handler(&pointers, code, ucontext);
- TRACE("SIGTRAP Signal was handled; continuing execution.\n");
+ TRACE("SIGTRAP signal was unhandled; chaining to previous sigaction\n");
+
+ if (g_previous_sigtrap.sa_sigaction != NULL)
+ {
+ g_previous_sigtrap.sa_sigaction(code, siginfo, context);
+ }
}
/*++
@@ -420,7 +381,7 @@ Parameters :
--*/
static void sigbus_handler(int code, siginfo_t *siginfo, void *context)
{
- check_pal_initialize(code);
+ check_pal_initialize(code, &g_previous_sigbus);
EXCEPTION_RECORD record;
EXCEPTION_POINTERS pointers;
native_context_t *ucontext;
@@ -445,7 +406,12 @@ static void sigbus_handler(int code, siginfo_t *siginfo, void *context)
common_signal_handler(&pointers, code, ucontext);
- TRACE("SIGBUS Signal was handled; continuing execution.\n");
+ TRACE("SIGBUS signal was unhandled; chaining to previous sigaction\n");
+
+ if (g_previous_sigbus.sa_sigaction != NULL)
+ {
+ g_previous_sigbus.sa_sigaction(code, siginfo, context);
+ }
}
/*++
@@ -494,25 +460,6 @@ BOOL SEHGetSafeState(CPalThread *pthrCurrent)
/*++
Function :
- fatal_signal_handler
-
- This signal handler has been replaced by the PAL signal handling thread : see seh.cpp
- Any signals assigned to this handler are intercepted by the signal handling thread, which
- initiates process termination and cleanup.
-
-Parameters :
- POSIX signal handler parameter list ("man sigaction" for details)
-
- (no return value)
---*/
-void fatal_signal_handler(int code, siginfo_t *siginfo, void *context)
-{
- check_pal_initialize(code);
- ASSERT("Should not reach fatal_signal_handler\n");
-}
-
-/*++
-Function :
common_signal_handler
common code for all signal handlers
@@ -530,7 +477,6 @@ Note:
static void common_signal_handler(PEXCEPTION_POINTERS pointers, int code,
native_context_t *ucontext)
{
- check_pal_initialize(code);
sigset_t signal_set;
CONTEXT context;
@@ -541,8 +487,7 @@ static void common_signal_handler(PEXCEPTION_POINTERS pointers, int code,
// Fill context record with required information. from pal.h :
// On non-Win32 platforms, the CONTEXT pointer in the
// PEXCEPTION_POINTERS will contain at least the CONTEXT_CONTROL registers.
- CONTEXTFromNativeContext(ucontext, &context,
- CONTEXT_CONTROL | CONTEXT_INTEGER);
+ CONTEXTFromNativeContext(ucontext, &context, CONTEXT_CONTROL | CONTEXT_INTEGER);
pointers->ContextRecord = &context;
@@ -566,40 +511,51 @@ Function :
Parameters :
int signal_id : signal to handle
SIGFUNC sigfunc : signal handler
+ previousAction : previous sigaction struct
(no return value)
note : if sigfunc is NULL, the default signal handler is restored
--*/
-void handle_signal(int signal_id, SIGFUNC sigfunc)
+void handle_signal(int signal_id, SIGFUNC sigfunc, struct sigaction *previousAction)
{
- struct sigaction act;
-
- act.sa_flags = SA_RESTART;
+ struct sigaction newAction;
- if( NULL == sigfunc )
- {
- act.sa_handler=SIG_DFL;
+ newAction.sa_flags = SA_RESTART;
#if HAVE_SIGINFO_T
- act.sa_sigaction=NULL;
-#endif /* HAVE_SIGINFO_T */
- }
- else
- {
-#if HAVE_SIGINFO_T
- act.sa_handler=NULL;
- act.sa_sigaction=sigfunc;
- act.sa_flags |= SA_SIGINFO;
+ newAction.sa_handler = NULL;
+ newAction.sa_sigaction = sigfunc;
+ newAction.sa_flags |= SA_SIGINFO;
#else /* HAVE_SIGINFO_T */
- act.sa_handler = SIG_DFL;
+ newAction.sa_handler = SIG_DFL;
#endif /* HAVE_SIGINFO_T */
+ sigemptyset(&newAction.sa_mask);
+
+ if (-1 == sigaction(signal_id, &newAction, previousAction))
+ {
+ ASSERT("handle_signal: sigaction() call failed with error code %d (%s)\n",
+ errno, strerror(errno));
}
- sigemptyset(&act.sa_mask);
+}
+
+/*++
+Function :
+ restore_signal
- if(-1==sigaction(signal_id,&act,NULL))
+ restore handler for specified signal
+
+Parameters :
+ int signal_id : signal to handle
+ previousAction : previous sigaction struct to restore
+
+ (no return value)
+--*/
+void restore_signal(int signal_id, struct sigaction *previousAction)
+{
+ if (-1 == sigaction(signal_id, previousAction, NULL))
{
- ASSERT("sigaction() call failed with error code %d (%s)\n",
- errno, strerror(errno));
+ ASSERT("restore_signal: sigaction() call failed with error code %d (%s)\n",
+ errno, strerror(errno));
}
}
@@ -612,14 +568,15 @@ Function :
Parameters :
int signal_id : signal to handle
+ previousAction : previous sigaction struct to restore
(no return value)
--*/
-inline void check_pal_initialize(int signal_id)
+inline void check_pal_initialize(int signal_id, struct sigaction *previousAction)
{
if (!PALIsInitialized())
{
- handle_signal(signal_id, NULL);
+ restore_signal(signal_id, previousAction);
kill(gPID, signal_id);
}
}
@@ -640,17 +597,9 @@ ControlHandlerThreadRoutine(
PVOID pvSignal
);
-static
-DWORD
-PALAPI
-ShutdownThreadRoutine(
- PVOID
- );
-
PAL_ERROR
StartExternalSignalHandlerThread(
- CPalThread *pthr
- )
+ CPalThread *pthr)
{
PAL_ERROR palError = NO_ERROR;
@@ -694,7 +643,6 @@ ExternalSignalHandlerThreadRoutine(
{
DWORD dwThreadId;
bool fContinue = TRUE;
- bool fShutdownThreadLaunched = FALSE;
HANDLE hThread;
int iError;
int iSignal;
@@ -716,54 +664,10 @@ ExternalSignalHandlerThreadRoutine(
(void)sigfillset(&sigsetAll);
(void)sigdelset(&sigsetAll, SIGPROF);
- (void)sigfillset(&sigsetWait);
-
-#if SIGWAIT_FAILS_WHEN_PASSED_FULL_SIGSET
- (void)sigdelset(&sigsetWait, SIGKILL);
- (void)sigdelset(&sigsetWait, SIGSTOP);
- (void)sigdelset(&sigsetWait, SIGWAITING);
- (void)sigdelset(&sigsetWait, SIGALRM1);
-#endif
-
- //
- // We don't want this thread to wait for signals that
- // we want to leave to the default handler (primarily
- // those involved with terminal or job control).
- //
- //
-
- (void)sigdelset(&sigsetWait, SIGURG);
- (void)sigdelset(&sigsetWait, SIGTSTP);
- (void)sigdelset(&sigsetWait, SIGCONT);
- (void)sigdelset(&sigsetWait, SIGCHLD);
- (void)sigdelset(&sigsetWait, SIGTTIN);
- (void)sigdelset(&sigsetWait, SIGTTOU);
- (void)sigdelset(&sigsetWait, SIGIO);
- (void)sigdelset(&sigsetWait, SIGWINCH);
-#ifdef SIGINFO
- (void)sigdelset(&sigsetWait, SIGINFO);
-#endif // SIGINFO
- (void)sigdelset(&sigsetWait, SIGPROF);
-
- //
- // Ideally, we'd like externally generated translated signals
- // (i.e., the signals that we convert to exceptions) to be directed
- // to this thread as well. Unfortunately on some platforms the sigwait
- // will take precedence over the synchronous signal on a thread within
- // this process -- the signal will get directed to this thread, instead
- // of the thread that executed the instruction that raised the signal.
- // This, needless to say, is not good for our EH mechanism.
- //
- // Furthermore, since these signals are not masked on other threads
- // on other platforms the externally generated signal will be directed
- // to one of those threads, instead of this one.
- //
- (void)sigdelset(&sigsetWait, SIGILL);
- (void)sigdelset(&sigsetWait, SIGTRAP);
- (void)sigdelset(&sigsetWait, SIGFPE);
- (void)sigdelset(&sigsetWait, SIGBUS);
- (void)sigdelset(&sigsetWait, SIGSEGV);
+ (void)sigemptyset(&sigsetWait);
+ (void)sigaddset(&sigsetWait, SIGINT);
+ (void)sigaddset(&sigsetWait, SIGQUIT);
//
// Mask off all signals for this thread
@@ -850,59 +754,13 @@ ExternalSignalHandlerThreadRoutine(
}
InternalCloseHandle(pthr, hThread);
-
break;
}
default:
- {
- //
- // Any other signal received externally is fatal. If we
- // haven't yet spun up a shutdown thread, do so now; if we
- // have, we want to wait for a bit (in the hope that the
- // shutdown thread is able to complete) and then exit.
- //
-
- if (fShutdownThreadLaunched)
- {
- sleep(c_iShutdownWaitTime);
- fContinue = FALSE;
- break;
- }
-
- //
- // Spin up a new thread to perform a graceful shutdown. As
- // with the console control handlers we want this thread
- // to continue to handle external signals.
- //
- // We're going to call TerminateProcess so it's OK for
- // this thread to be a worker thread -- DllMain routines
- // will not be called.
- //
-
- fShutdownThreadLaunched = TRUE;
-
- palError = InternalCreateThread(
- pthr,
- NULL,
- 0,
- ShutdownThreadRoutine,
- NULL,
- 0,
- PalWorkerThread,
- &dwThreadId,
- &hThread
- );
-
- if (NO_ERROR != palError)
- {
- fContinue = FALSE;
- break;
- }
-
- InternalCloseHandle(pthr, hThread);
+ ASSERT("Unexpect signal %d in signal thread\n", iSignal);
+ fContinue = FALSE;
break;
- }
}
}
@@ -927,15 +785,4 @@ ControlHandlerThreadRoutine(
return 0;
}
-static
-DWORD
-PALAPI
-ShutdownThreadRoutine(
- PVOID
- )
-{
- TerminateProcess(GetCurrentProcess(), CONTROL_C_EXIT);
- return 0;
-}
-
#endif // !HAVE_MACH_EXCEPTIONS
diff --git a/src/pal/src/exception/signal.hpp b/src/pal/src/exception/signal.hpp
index 4940515577..70a5145fc9 100644
--- a/src/pal/src/exception/signal.hpp
+++ b/src/pal/src/exception/signal.hpp
@@ -30,11 +30,11 @@ Function :
Set-up signal handlers to catch signals and translate them to exceptions
Parameters :
- PAL initialize flags
+ None
(no return value)
--*/
-void SEHInitializeSignals(DWORD flags);
+void SEHInitializeSignals();
/*++
Function :
@@ -44,7 +44,7 @@ Function :
(no parameters, no return value)
--*/
-void SEHCleanupSignals(DWORD flags);
+void SEHCleanupSignals();
#if (__GNUC__ > 3 || \
(__GNUC__ == 3 && __GNUC_MINOR__ > 2))
diff --git a/src/pal/src/include/pal/seh.hpp b/src/pal/src/include/pal/seh.hpp
index 399a417ea7..b6bbad06a7 100644
--- a/src/pal/src/include/pal/seh.hpp
+++ b/src/pal/src/include/pal/seh.hpp
@@ -53,12 +53,12 @@ Function :
Clean up SEH-related stuff(signals, etc)
Parameters:
- flags : PAL initialize flags
+ None
(no return value)
--*/
VOID
-SEHCleanup(DWORD flags);
+SEHCleanup();
/*++
Function:
diff --git a/src/pal/src/init/pal.cpp b/src/pal/src/init/pal.cpp
index 7135e0c5c0..0e33e81223 100644
--- a/src/pal/src/init/pal.cpp
+++ b/src/pal/src/init/pal.cpp
@@ -534,7 +534,7 @@ CLEANUP10:
CLEANUP8:
MAPCleanup();
CLEANUP6:
- SEHCleanup(flags);
+ SEHCleanup();
CLEANUP5:
PROCCleanupInitialProcess();
CLEANUP4:
@@ -847,7 +847,7 @@ PALCommonCleanup(PALCLEANUP_STEP step, BOOL full_cleanup)
LOADFreeModules requires SEH to be functional when calling DllMain.
Therefore SEHCleanup must go between LOADFreeModules and
PROCCleanupInitialProcess */
- SEHCleanup(PAL_INITIALIZE_ALL);
+ SEHCleanup();
PROCCleanupInitialProcess();
}
diff --git a/src/pal/src/thread/thread.cpp b/src/pal/src/thread/thread.cpp
index f91266ed78..738ada047d 100644
--- a/src/pal/src/thread/thread.cpp
+++ b/src/pal/src/thread/thread.cpp
@@ -2433,6 +2433,9 @@ PAL_GetStackBase()
pthread_t thread = pthread_self();
+ status = pthread_attr_init(&attr);
+ _ASSERT_MSG(status == 0, "pthread_attr_init call failed");
+
#if HAVE_PTHREAD_ATTR_GET_NP
status = pthread_attr_get_np(thread, &attr);
#elif HAVE_PTHREAD_GETATTR_NP
@@ -2465,6 +2468,9 @@ PAL_GetStackLimit()
pthread_t thread = pthread_self();
+ status = pthread_attr_init(&attr);
+ _ASSERT_MSG(status == 0, "pthread_attr_init call failed");
+
#if HAVE_PTHREAD_ATTR_GET_NP
status = pthread_attr_get_np(thread, &attr);
#elif HAVE_PTHREAD_GETATTR_NP
diff --git a/src/pal/src/thread/threadsusp.cpp b/src/pal/src/thread/threadsusp.cpp
index b8bab873e6..d3602b34a2 100644
--- a/src/pal/src/thread/threadsusp.cpp
+++ b/src/pal/src/thread/threadsusp.cpp
@@ -1674,35 +1674,33 @@ CThreadSuspensionInfo::HandleSuspendSignal(
CPalThread *pthrTarget
)
{
- if (!GetSuspendSignalSent())
+ if (GetSuspendSignalSent())
{
- ASSERT("Entered suspend handler (by receiving SIGUSR1) but not due to SuspendThread.\n");
- return;
- }
- SetSuspendSignalSent(FALSE);
-
- if (IsSuspensionStateSafe())
- {
- SetSuspPending(FALSE);
- if (!pthrTarget->GetCreateSuspended())
+ SetSuspendSignalSent(FALSE);
+
+ if (IsSuspensionStateSafe())
{
- /* Note that we don't call sem_post when CreateSuspended is true.
- This is to handle the scenario where a thread suspends itself and
- another thread then attempts to suspend that thread. It won't wait
- on the semaphore if the self suspending thread already posted
- but didn't reach the matching wait. */
- PostOnSuspendSemaphore();
+ SetSuspPending(FALSE);
+ if (!pthrTarget->GetCreateSuspended())
+ {
+ /* Note that we don't call sem_post when CreateSuspended is true.
+ This is to handle the scenario where a thread suspends itself and
+ another thread then attempts to suspend that thread. It won't wait
+ on the semaphore if the self suspending thread already posted
+ but didn't reach the matching wait. */
+ PostOnSuspendSemaphore();
+ }
+ else
+ {
+ pthrTarget->SetStartStatus(TRUE);
+ }
+ sigsuspend(&smSuspmask);
}
- else
+ else
{
- pthrTarget->SetStartStatus(TRUE);
- }
- sigsuspend(&smSuspmask);
+ SetSuspPending(TRUE);
+ }
}
- else
- {
- SetSuspPending(TRUE);
- }
}
/*++
@@ -1720,27 +1718,25 @@ continue execution.
void
CThreadSuspensionInfo::HandleResumeSignal()
{
- if (!GetResumeSignalSent())
- {
- ASSERT("Entered resume handler (by receiving SIGUSR2) but not due to ResumeThread.\n");
- return;
- }
- SetResumeSignalSent(FALSE);
-
- if (GetSuspCount() != 0)
- {
- ASSERT("Should not be resuming a thread whose suspension count is %d.\n", GetSuspCount());
- return;
- }
-
- // This thread is no longer suspended - if it self suspended,
- // then its self suspension field should now be set to FALSE.
- if (GetSelfSusp())
+ if (GetResumeSignalSent())
{
- SetSelfSusp(FALSE);
+ SetResumeSignalSent(FALSE);
+
+ if (GetSuspCount() != 0)
+ {
+ ASSERT("Should not be resuming a thread whose suspension count is %d.\n", GetSuspCount());
+ return;
+ }
+
+ // This thread is no longer suspended - if it self suspended,
+ // then its self suspension field should now be set to FALSE.
+ if (GetSelfSusp())
+ {
+ SetSelfSusp(FALSE);
+ }
+
+ PostOnResumeSemaphore();
}
-
- PostOnResumeSemaphore();
}
#else // USE_SIGNALS_FOR_THREAD_SUSPENSION
diff --git a/src/pal/tools/gen-buildsys-win.bat b/src/pal/tools/gen-buildsys-win.bat
index 6dc56585fa..56b22f221f 100644
--- a/src/pal/tools/gen-buildsys-win.bat
+++ b/src/pal/tools/gen-buildsys-win.bat
@@ -5,7 +5,7 @@ rem This file invokes cmake and generates the build system for windows.
set argC=0
for %%x in (%*) do Set /A argC+=1
-if NOT %argC%==1 GOTO :USAGE
+if NOT %argC%==2 GOTO :USAGE
if %1=="/?" GOTO :USAGE
setlocal
@@ -15,20 +15,24 @@ set "basePath=%basePath:"=%"
:: remove trailing slash
if %basePath:~-1%==\ set "basePath=%basePath:~0,-1%"
+set __VSString=12 2013
+if /i "%2" == "vs2015" (set __VSString=14 2015)
+
if defined CMakePath goto DoGen
:: Eval the output from probe-win1.ps1
for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy RemoteSigned "& .\probe-win.ps1"') do %%a
:DoGen
-"%CMakePath%" "-DCMAKE_USER_MAKE_RULES_OVERRIDE=%basePath%\windows-compiler-override.txt" -G "Visual Studio 12 2013 Win64" %1
+"%CMakePath%" "-DCMAKE_USER_MAKE_RULES_OVERRIDE=%basePath%\windows-compiler-override.txt" -G "Visual Studio %__VSString% Win64" %1
endlocal
GOTO :DONE
:USAGE
echo "Usage..."
- echo "gen-buildsys-win.bat <path to top level CMakeLists.txt>"
+ echo "gen-buildsys-win.bat <path to top level CMakeLists.txt> <VSVersion>"
echo "Specify the path to the top level CMake file - <ProjectK>/src/NDP"
+ echo "Specify the VSVersion to be used - VS2013 or VS2015"
EXIT /B 1
:DONE
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp
index 6e26ceb7d1..c887ceacde 100644
--- a/src/vm/corhost.cpp
+++ b/src/vm/corhost.cpp
@@ -1945,8 +1945,10 @@ HRESULT CorHost2::SetStartupFlags(STARTUP_FLAGS flag)
}
CONTRACTL_END;
- if(g_fEEStarted)
+ if (m_fStarted)
+ {
return HOST_E_INVALIDOPERATION;
+ }
if (CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_gcServer) != 0)
{
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index 2a5ad89798..5f87ccf093 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -4905,7 +4905,7 @@ Function :
IsDivByZeroAnIntegerOverflow
Check if a division by zero exception is in fact a division overflow. The
- x64 processor generate the same exception in both cases for the IDIV
+ x64 processor generate the same exception in both cases for the IDIV / DIV
instruction. So we need to decode the instruction argument and check
whether it was zero or not.
@@ -4933,16 +4933,17 @@ bool IsDivByZeroAnIntegerOverflow(PCONTEXT pContext)
DWORD64 divisor = 0;
- // Check if the instruction is IDIV. The instruction code includes the three
- // 'reg' bits in the ModRM byte.
- if ((code == 0xF7 || code == 0xF6) && (((*ip & 0x38) >> 3) == 7))
+ // Check if the instruction is IDIV or DIV. The instruction code includes the three
+ // 'reg' bits in the ModRM byte. These are 7 for IDIV and 6 for DIV
+ BYTE regBits = (*ip & 0x38) >> 3;
+ if ((code == 0xF7 || code == 0xF6) && (regBits == 7 || regBits == 6))
{
bool is8Bit = (code == 0xF6);
divisor = GetModRMOperandValue(rex, ip, pContext, is8Bit, hasOpSizePrefix);
}
else
{
- _ASSERTE(!"Invalid instruction (expected IDIV)");
+ _ASSERTE(!"Invalid instruction (expected IDIV or DIV)");
}
// If the division operand is zero, it was division by zero. Otherwise the failure
@@ -4954,6 +4955,10 @@ bool IsDivByZeroAnIntegerOverflow(PCONTEXT pContext)
VOID PALAPI HandleHardwareException(PAL_SEHException* ex)
{
+ if (!g_fEEStarted)
+ {
+ return;
+ }
if (ex->ExceptionRecord.ExceptionCode != STATUS_BREAKPOINT && ex->ExceptionRecord.ExceptionCode != STATUS_SINGLE_STEP)
{
// A hardware exception is handled only if it happened in a jitted code or
@@ -5000,13 +5005,13 @@ VOID PALAPI HandleHardwareException(PAL_SEHException* ex)
UNREACHABLE();
}
}
- else
+ else
{
// This is a breakpoint or single step stop, we report it to the debugger.
- Thread *pThread = GetThread();
+ Thread *pThread = GetThread();
if (pThread != NULL && g_pDebugInterface != NULL)
{
- if (ex->ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
+ if (ex->ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT)
{
// If this is breakpoint context, it is set up to point to an instruction after the break instruction.
// But debugger expects to see context that points to the break instruction, that's why we correct it.
@@ -5015,13 +5020,13 @@ VOID PALAPI HandleHardwareException(PAL_SEHException* ex)
}
if (g_pDebugInterface->FirstChanceNativeException(&ex->ExceptionRecord,
- &ex->ContextRecord,
- ex->ExceptionRecord.ExceptionCode,
- pThread))
+ &ex->ContextRecord,
+ ex->ExceptionRecord.ExceptionCode,
+ pThread))
{
RtlRestoreContext(&ex->ContextRecord, &ex->ExceptionRecord);
- }
- else
+ }
+ else
{
_ASSERTE(!"Looks like a random breakpoint/trap that was not prepared by the EE debugger");
}
diff --git a/tests/buildtest.cmd b/tests/buildtest.cmd
index c8823f961e..e2b45b1f1e 100644
--- a/tests/buildtest.cmd
+++ b/tests/buildtest.cmd
@@ -20,6 +20,9 @@ if /i "%1" == "release" (set __BuildType=Release&shift&goto Arg_Loop)
if /i "%1" == "clean" (set __CleanBuild=1&shift&goto Arg_Loop)
+if /i "%1" == "vs2013" (set __VSVersion=%1&set __VSProductVersion=120&shift&goto Arg_Loop)
+if /i "%1" == "vs2015" (set __VSVersion=%1&set __VSProductVersion=140&shift&goto Arg_Loop)
+
goto Usage
@@ -29,6 +32,9 @@ goto Usage
if not defined __BuildArch set __BuildArch=x64
if not defined __BuildType set __BuildType=Debug
if not defined __BuildOS set __BuildOS=Windows_NT
+:: Default to VS2013
+if not defined __VSVersion set __VSVersion=vs2013
+if not defined __VSProductVersion set __VSProductVersion=120
set "__TestBinDir=%__RootBinDir%\tests\%__BuildOS%.%__BuildArch%.%__BuildType%"
:: We have different managed and native intermediate dirs because the managed bits will include
@@ -73,19 +79,21 @@ echo.
for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy RemoteSigned "& ""%__SourceDir%\pal\tools\probe-win.ps1"""') do %%a
:: Check presence of VS
-if defined VS120COMNTOOLS goto CheckVSExistence
+if defined VS%__VSProductVersion%COMNTOOLS goto CheckVSExistence
echo Installation of VS 2013 is a pre-requisite to build this repository.
goto :eof
:CheckVSExistence
-:: Does VS 2013 really exist?
-if exist "%VS120COMNTOOLS%\..\IDE\devenv.exe" goto CheckMSBuild
+:: Does VS 2013 or VS 2015 really exist?
+if exist "!VS%__VSProductVersion%COMNTOOLS!\..\IDE\devenv.exe" goto CheckMSBuild
echo Installation of VS 2013 is a pre-requisite to build this repository.
goto :eof
-:CheckMSBuild
+:CheckMSBuild
+if /i "%__VSVersion%" =="vs2015" goto MSBuild14
set _msbuildexe="%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles%\MSBuild\12.0\Bin\MSBuild.exe"
+:MSBuild14
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles%\MSBuild\14.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% echo Error: Could not find MSBuild.exe. Please see https://github.com/dotnet/coreclr/wiki/Developer%%20Guide for build instructions. && exit /b 1
@@ -97,7 +105,7 @@ echo Commencing build of native test components for %__BuildArch%/%__BuildType%
echo.
:: Set the environment for the native build
-call "%VS120COMNTOOLS%..\..\VC\vcvarsall.bat" x86_amd64
+call "!VS%__VSProductVersion%COMNTOOLS!..\..\VC\vcvarsall.bat" x86_amd64
if exist "%VSINSTALLDIR%DIA SDK" goto GenVSSolution
echo Error: DIA SDK is missing at "%VSINSTALLDIR%DIA SDK". ^
@@ -109,7 +117,7 @@ goto :eof
:GenVSSolution
:: Regenerate the VS solution
pushd "%__NativeTestIntermediatesDir%"
-call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectFilesDir%\"
+call "%__SourceDir%\pal\tools\gen-buildsys-win.bat" "%__ProjectFilesDir%\" %__VSVersion%
popd
:BuildComponents
@@ -133,7 +141,7 @@ endlocal
REM setlocal to prepare for vsdevcmd.bat
setlocal
:: Set the environment for the managed build- Vs cmd prompt
-call "%VS120COMNTOOLS%\VsDevCmd.bat"
+call "!VS%__VSProductVersion%COMNTOOLS!\VsDevCmd.bat"
if not defined VSINSTALLDIR echo Error: build.cmd should be run from a Visual Studio Command Prompt. Please see https://github.com/dotnet/coreclr/wiki/Developer%%20Guide for build instructions. && exit /b 1
@@ -168,9 +176,10 @@ goto :eof
:Usage
echo.
echo Usage:
-echo %0 BuildArch BuildType [clean] where:
+echo %0 BuildArch BuildType [clean] [vsversion] where:
echo.
echo BuildArch can be: x64
echo BuildType can be: Debug, Release
echo Clean - optional argument to force a clean build.
+echo VSVersion - optional argument to use VS2013 or VS2015 (default VS2013)
exit /b 1
diff --git a/tests/runtest.cmd b/tests/runtest.cmd
index 4978618980..a162d791c7 100644
--- a/tests/runtest.cmd
+++ b/tests/runtest.cmd
@@ -1,6 +1,11 @@
@echo off
-setlocal
+setlocal EnableDelayedExpansion
set __ProjectFilesDir=%~dp0
+
+:: Default to VS2013
+set __VSVersion=VS2013
+set __VSProductVersion=120
+
:Arg_Loop
if "%1" == "" goto ArgsDone
if /i "%1" == "x64" (set __BuildArch=x64&set __MSBuildBuildArch=x64&shift&goto Arg_Loop)
@@ -8,8 +13,12 @@ if /i "%1" == "x64" (set __BuildArch=x64&set __MSBuildBuildArch=x64&shift&got
if /i "%1" == "debug" (set __BuildType=debug&shift&goto Arg_Loop)
if /i "%1" == "release" (set __BuildType=release&shift&goto Arg_Loop)
if /i "%1" == "SkipWrapperGeneration" (set __SkipWrapperGeneration=true&shift&goto Arg_Loop)
+if /i "%1" == "Exclude" (set __Exclude=%2&shift&shift&goto Arg_Loop)
if /i "%1" == "TestEnv" (set __TestEnv=%2&shift&shift&goto Arg_Loop)
+if /i "%1" == "vs2013" (set __VSVersion=%1&set __VSProductVersion=120&shift&goto Arg_Loop)
+if /i "%1" == "vs2015" (set __VSVersion=%1&set __VSProductVersion=140&shift&goto Arg_Loop)
+
if /i "%1" == "/?" (goto Usage)
set Core_Root=%1
@@ -18,19 +27,21 @@ shift
:: Check prerequisites
:: Check presence of VS
-if defined VS120COMNTOOLS goto CheckMSbuild
+if defined VS%__VSProductVersion%COMNTOOLS goto CheckMSbuild
echo Installation of VS 2013 is a pre-requisite to build this repository.
goto :eof
-:CheckMSBuild
+:CheckMSBuild
+if /i "%__VSVersion%" =="vs2015" goto MSBuild14
set _msbuildexe="%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles%\MSBuild\12.0\Bin\MSBuild.exe"
+:MSBuild14
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% set _msbuildexe="%ProgramFiles%\MSBuild\14.0\Bin\MSBuild.exe"
if not exist %_msbuildexe% echo Error: Could not find MSBuild.exe. Please see https://github.com/dotnet/corefx/wiki/Developer%%20Guide for build instructions. && exit /b 1
:: Set the environment for the build- Vs cmd prompt
-call "%VS120COMNTOOLS%\VsDevCmd.bat"
+call "!VS%__VSProductVersion%COMNTOOLS!\VsDevCmd.bat"
if not defined VSINSTALLDIR echo Error: runtest.cmd should be run from a Visual Studio Command Prompt. Please see https://github.com/dotnet/coreclr/wiki/Developer%%20Guide for build instructions. && exit /b 1
@@ -55,6 +66,7 @@ set Core_Root=%__BinDir%
if not exist %XunitTestBinBase% echo Error: Ensure the Test Binaries are built and are present at %XunitTestBinBase%, Run - buildtest.cmd %__BuildArch% %__BuildType% to build the tests first. && exit /b 1
if "%Core_Root%" == "" echo Error: Ensure you have done a successful build of the Product and Run - runtest BuildArch BuildType {path to product binaries}. && exit /b 1
if not exist %Core_Root%\coreclr.dll echo Error: Ensure you have done a successful build of the Product and %Core_Root% contains runtime binaries. && exit /b 1
+if not "%__Exclude%"=="" (if not exist %__Exclude% echo Error: Exclusion .targets file not found && exit /b 1)
if not "%__TestEnv%"=="" (if not exist %__TestEnv% echo Error: Test Environment script not found && exit /b 1)
if not exist %__LogsDir% md %__LogsDir%
@@ -130,12 +142,14 @@ goto :eof
:Usage
echo.
echo Usage:
-echo %0 BuildArch BuildType [SkipWrapperGeneration] [TestEnv TEST_ENV_SCRIPT] CORE_ROOT where:
+echo %0 BuildArch BuildType [SkipWrapperGeneration] [Exclude EXCLUSION_TARGETS] [TestEnv TEST_ENV_SCRIPT] [vsversion] CORE_ROOT where:
echo.
echo BuildArch is x64
echo BuildType can be: Debug, Release
echo SkipWrapperGeneration- Optional parameter - this will run the same set of tests as the last time it was run
+echo Exclude- Optional parameter - this will exclude individual tests from running, specified by ExcludeList ItemGroup in an .targets file.
echo TestEnv- Optional parameter - this will run a custom script to set custom test envirommnent settings.
+echo VSVersion- optional argument to use VS2013 or VS2015 (default VS2013)
echo CORE_ROOT The path to the runtime
exit /b 1
diff --git a/tests/runtest.proj b/tests/runtest.proj
index 8265fcb35a..b703e20ae7 100644
--- a/tests/runtest.proj
+++ b/tests/runtest.proj
@@ -49,6 +49,7 @@
+ <Import Project="$(__Exclude)" Condition="'$(__Exclude)' != '' AND '$(XunitTestBinBase)' != ''" />
<Target Name="CreateXunitWrapper"
DependsOnTargets="CreateXunitFacts">
@@ -213,10 +214,15 @@ namespace $([System.String]::Copy($(Category)).Replace(".","_").Replace("\","").
]]>
</_XunitEpilog>
</PropertyGroup>
+
+ <ItemGroup>
+ <CanonicalExcludeList Include="%(ExcludeList.FullPath)" Condition="'$(__Exclude)' != ''"/>
+ </ItemGroup>
+
<ItemGroup>
<AllCMDsPresent Include="$(_CMDDIR)\**\*.cmd" />
- <AllCMDExcludeFilter Include="@(AllCMDsPresent)" Exclude="@AllRunnableTestPaths"/>
- <AllCMDs Include="@(AllCMDsPresent)" Exclude="@AllCMDExcludeFilter"/>
+ <AllCMDExcludeFilter Include="@(CanonicalExcludeList)" Condition="'$(__Exclude)' != ''"/>
+ <AllCMDs Include="@(AllCMDsPresent)" Exclude="@(AllCMDExcludeFilter)"/>
<AllCommamds Include="@(AllCMDs)" >
@@ -330,13 +336,12 @@ public class $([System.String]::Copy('%(AllCMDs.FullPath)').Replace("$(_CMDDIR)"
<MSBuild Projects="$(MSBuildProjectFile)"
Targets="CreateAllWrappers"
- Properties="_CMDDIR=%(TestDirectories.Identity)"
- Condition=" '$(NoBuild)'!='true' "/>
+ Properties="_CMDDIR=%(TestDirectories.Identity)" />
- <MSBuild Projects="$(MSBuildProjectFile)" Targets="CopyDependecyToCoreRoot"
+ <MSBuild Projects="$(MSBuildProjectFile)" Targets="CopyDependecyToCoreRoot"
Condition=" '$(NoRun)'!='true' "/>
- <MSBuild Projects="$(MSBuildProjectFile)" Targets="RunTests"
+ <MSBuild Projects="$(MSBuildProjectFile)" Targets="RunTests"
Condition=" '$(NoRun)'!='true' "/>
</Target>