Skip to content

Commit

Permalink
Add profiler auto instrumentation (#1534)
Browse files Browse the repository at this point in the history
This commit adds profiler auto instrumentation to the
Elastic APM .NET agent solution.

Profiler auto instrumentation uses the CLR profiling APIs
to instrument methods of interest at runtime, by signaling
to the runtime to load an unmanaged profiler into the process
using profiling environment variables.

The approach comprises:

1. A CLR profiler written in Rust
2. Supporting managed assemblies containing methods
that will be inserted into rewritten IL and called, to start
and end transactions and spans.

Initial integrations are available for common ADO.NET providers
and Kafka, with more to follow in the future.

The profiler auto instrumentation approach is currently
an alpha release, as indicated by the version number
in src/elastic_apm_profiler/Cargo.toml.

Closes #1522
  • Loading branch information
russcam authored Nov 4, 2021
1 parent b33d209 commit bab7761
Show file tree
Hide file tree
Showing 328 changed files with 45,909 additions and 605 deletions.
18 changes: 15 additions & 3 deletions .ci/docker/sdk-linux/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,23 @@ RUN apt update \
&& add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" \
&& apt -qq update \
&& apt-get -qq install -y docker-ce docker-ce-cli containerd.io \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
--no-install-recommends

# Install terraform
RUN curl -fsSL https://apt.releases.hashicorp.com/gpg | apt-key add - \
&& apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main" \
&& apt-get update \
&& apt-get install terraform
&& apt-get -qq install -y terraform

# Install rust
ENV RUSTUP_HOME='/cargo'
ENV CARGO_HOME='/cargo'
ENV PATH="/cargo/bin:${PATH}"
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
RUN rustup default 1.54.0

# Install cargo make
RUN apt-get -qq install -y build-essential libssl-dev pkg-config \
--no-install-recommends \
&& rm -rf /var/lib/apt/lists/*
RUN cargo install --force cargo-make
6 changes: 6 additions & 0 deletions .ci/linux/remove-projects.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ set -euxo pipefail
dotnet sln remove sample/AspNetFullFrameworkSampleApp/AspNetFullFrameworkSampleApp.csproj
dotnet sln remove src/Elastic.Apm.AspNetFullFramework/Elastic.Apm.AspNetFullFramework.csproj
dotnet sln remove test/Elastic.Apm.AspNetFullFramework.Tests/Elastic.Apm.AspNetFullFramework.Tests.csproj

# Remove Startup hooks test project. tested separately
dotnet sln remove test/Elastic.Apm.StartupHook.Tests/Elastic.Apm.StartupHook.Tests.csproj

# Remove Profiler test project. tested separately
dotnet sln remove test/Elastic.Apm.Profiler.Managed.Tests/Elastic.Apm.Profiler.Managed.Tests.csproj
24 changes: 24 additions & 0 deletions .ci/linux/test-profiler.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash
#
# This script runs the tests and stored the test ouptut in a JUnit xml file
# defined in the test_results folder
#
set -euxo pipefail

cargo make test

dotnet test -c Release test/Elastic.Apm.Profiler.Managed.Tests/Elastic.Apm.Profiler.Managed.Tests.csproj \
--verbosity normal \
--results-directory target \
--diag target/diag-profiler.log \
--logger:"junit;LogFilePath=junit-{framework}-{assembly}.xml;MethodFormat=Class;FailureBodyFormat=Verbose" \
--collect:"XPlat Code Coverage" \
--settings coverlet.runsettings \
--blame-hang \
--blame-hang-timeout 10m \
/p:CollectCoverage=true \
/p:CoverletOutputFormat=cobertura \
/p:CoverletOutput=test_results/Coverage/ \
/p:Threshold=0 \
/p:ThresholdType=branch \
/p:ThresholdStat=total
12 changes: 12 additions & 0 deletions .ci/linux/test-startuphooks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env bash
#
# This script runs the tests and stored the test ouptut in a JUnit xml file
# defined in the test_results folder
#
set -euxo pipefail

dotnet test -c Release test/Elastic.Apm.StartupHook.Tests/Elastic.Apm.StartupHook.Tests.csproj --no-build \
--verbosity normal \
--results-directory target \
--diag target/diag-startuphook.log \
--logger:"junit;LogFilePath=junit-{framework}-{assembly}.xml;MethodFormat=Class;FailureBodyFormat=Verbose"
5 changes: 1 addition & 4 deletions .ci/linux/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@
#
set -euxo pipefail

# Remove Full Framework projects
# Remove projects
.ci/linux/remove-projects.sh

# Build agent zip file
./build.sh agent-zip

# Run tests for all solution
dotnet test -c Release ElasticApmAgent.sln \
--verbosity normal \
Expand Down
3 changes: 3 additions & 0 deletions .ci/windows/dotnet.bat
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,7 @@ dotnet sln remove test/Elastic.Apm.MongoDb.Tests/Elastic.Apm.MongoDb.Tests.cspro
:: Remove startup hooks tests, which are tested separately- require agent zip to be built
dotnet sln remove test/Elastic.Apm.StartupHook.Tests/Elastic.Apm.StartupHook.Tests.csproj

:: Remove profiler tests, which are tested separately- require profiler to be built
dotnet sln remove test/Elastic.Apm.Profiler.Managed.Tests/Elastic.Apm.Profiler.Managed.Tests.csproj

dotnet build -c Release --verbosity detailed
2 changes: 1 addition & 1 deletion .ci/windows/msbuild-tools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ Start-Process "C:\tools\vs_BuildTools.exe" -ArgumentList "--add", "Microsoft.Vis
"--add", "Microsoft.VisualStudio.Workload.NetCoreBuildTools;includeRecommended;includeOptional", `
"--add", "Microsoft.VisualStudio.Workload.MSBuildTools", `
"--add", "Microsoft.VisualStudio.Workload.WebBuildTools;includeRecommended;includeOptional", `
"--quiet", "--norestart", "--nocache" -NoNewWindow -Wait
"--quiet", "--norestart", "--nocache" -NoNewWindow -Wait;
2 changes: 2 additions & 0 deletions .ci/windows/msbuild.bat
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
::
echo "Prepare context for VsDevCmd.bat"
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\Tools\VsDevCmd.bat"

dotnet nuget add source --name nuget.org https://api.nuget.org/v3/index.json
nuget restore -verbosity detailed -NonInteractive

msbuild /p:Configuration=Release
17 changes: 17 additions & 0 deletions .ci/windows/test-profiler.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
cargo make test

dotnet test -c Release test\Elastic.Apm.Profiler.Managed.Tests\Elastic.Apm.Profiler.Managed.Tests.csproj ^
--verbosity normal ^
--results-directory target ^
--diag target\diag-profiler.log ^
--logger:"junit;LogFilePath=junit-{framework}-{assembly}.xml;MethodFormat=Class;FailureBodyFormat=Verbose" ^
--collect:"XPlat Code Coverage" ^
--settings coverlet.runsettings ^
--blame-hang ^
--blame-hang-timeout 10m ^
/p:CollectCoverage=true ^
/p:CoverletOutputFormat=cobertura ^
/p:CoverletOutput=test_results/Coverage/ ^
/p:Threshold=0 ^
/p:ThresholdType=branch ^
/p:ThresholdStat=total
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
dotnet test -c Release test\Elastic.Apm.StartupHook.Tests --no-build ^
dotnet test -c Release test\Elastic.Apm.StartupHook.Tests\Elastic.Apm.StartupHook.Tests.csproj --no-build ^
--verbosity normal ^
--results-directory target ^
--diag target\diag-startuphook.log ^
Expand Down
16 changes: 15 additions & 1 deletion .ci/windows/tools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,29 @@ Add-WindowsFeature NET-Framework-45-ASPNET
Add-WindowsFeature Web-Asp-Net45

# Install .Net SDKs
Write-Host "Install .Net SDKs"
choco install dotnetcore-sdk -m -y --no-progress -r --version 2.1.505
choco install dotnetcore-sdk -m -y --no-progress -r --version 2.2.104
choco install dotnetcore-sdk -m -y --no-progress -r --version 3.0.103
choco install dotnetcore-sdk -m -y --no-progress -r --version 3.1.100

choco install dotnet-sdk -m -y --no-progress -r --version 5.0.100

# Install NuGet Tool
choco install nuget.commandline -y --no-progress -r --version 5.8.0

# Install vswhere
choco install vswhere -y --no-progress -r --version 2.8.4

# Install rust
Write-Host "Install rust-ms"
choco install rust-ms -y --no-progress -r --version 1.54.0

# Download and install cargo make
Write-Host "Download cargo-make"
Invoke-WebRequest -UseBasicParsing `
-Uri "https://github.com/sagiegurari/cargo-make/releases/download/0.35.0/cargo-make-v0.35.0-x86_64-pc-windows-msvc.zip" `
-OutFile "C:\tools\cargo-make.zip"

Write-Host "Unzip cargo-make"
New-Item -ItemType directory -Path C:\tools\cargo
Expand-Archive -LiteralPath C:\tools\cargo-make.zip -DestinationPath C:\tools\cargo
1 change: 0 additions & 1 deletion .ci/windows/zip.bat

This file was deleted.

6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,9 @@ terraform.tfstate.backup

# This file is generated on build
src/Elastic.Apm.MongoDb/LICENSE

# Rust files
target/
Cargo.lock
expanded.rs

4 changes: 4 additions & 0 deletions .rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
reorder_imports = true

# requires nightly rustfmt
imports_granularity = "Crate"
50 changes: 47 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,54 @@ feedback and ideas are always welcome.

## Prerequisites

In order to build the source code of the .NET APM Agent you need
* .NET Core 2.1 or later
### .NET source

You can use any IDE that supports .NET Core development and you can use any OS that is supported by .NET Core.
In order to build the .NET source code, you'll need
* [.NET 5.0 or later](https://dotnet.microsoft.com/download/dotnet/5.0)
* **If** you're running on Windows **and** also wish to build projects that target .NET Framework,
you'll need a minimum of .NET Framework 4.6.1 installed.

You can use any IDE that supports .NET development, and you can use any OS that is supported by .NET.

### Rust source

In order to build the CLR profiler source code, you'll need
* [Rust 1.54 or later](https://www.rust-lang.org/tools/install)
* [Cargo make](https://github.com/sagiegurari/cargo-make#installation)

You can use any IDE that supports Rust development; we typically use [CLion](https://www.jetbrains.com/clion/)
with the [Rust plugin](https://plugins.jetbrains.com/plugin/8182-rust/docs),
or [VS Code](https://code.visualstudio.com/)
with the [Rust extension](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust).

## Work flow

The solution contains a build project for performing build tasks, which can be invoked
with the `build.bat` or `build.sh` scripts in the solution root.

To see the list of targets

Windows
```shell
.\build.bat --list-targets
```

Linux
```shell
./build.sh --list-targets
```

To perform a build of projects (the default task)

Windows
```shell
.\build.bat
```

Linux
```shell
./build.sh
```

## Code contributions (please read this before your first PR)

Expand Down
12 changes: 12 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[workspace]

members = [
"src/elastic_apm_profiler",
]

# default release profile: https://doc.rust-lang.org/cargo/reference/profiles.html#release
[profile.release]
lto = true
codegen-units = 1
# reduce binary size by not unwinding on panic to get a backtrace
#panic = "abort"
98 changes: 98 additions & 0 deletions ElasticApmAgent.sln
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,34 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Azure.CosmosDb"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Azure.CosmosDb.Tests", "test\Elastic.Apm.Azure.CosmosDb.Tests\Elastic.Apm.Azure.CosmosDb.Tests.csproj", "{0EEA16C4-C7DF-4D90-94C2-009417D765AC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Profiler.Managed", "src\Elastic.Apm.Profiler.Managed\Elastic.Apm.Profiler.Managed.csproj", "{A88A3877-05D6-45B2-94E4-5C583BD6EEDC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Profiler.Managed.Loader", "src\Elastic.Apm.Profiler.Managed.Loader\Elastic.Apm.Profiler.Managed.Loader.csproj", "{F1DD170E-2DD8-4CBD-A2BB-C19CF0033982}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NpgsqlSample", "sample\NpgsqlSample\NpgsqlSample.csproj", "{BA2D3FCD-C25E-4E34-9A30-BE1FB16E1841}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Profiler.Managed.Tests", "test\Elastic.Apm.Profiler.Managed.Tests\Elastic.Apm.Profiler.Managed.Tests.csproj", "{4983083A-87AD-496E-B0BC-84C8097D0590}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.AdoNet", "sample\Elastic.Apm.AdoNet\Elastic.Apm.AdoNet.csproj", "{14BEE605-6180-4B9E-87F5-A24BA79461B5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.AdoNet.NetStandard", "sample\Elastic.Apm.AdoNet.NetStandard\Elastic.Apm.AdoNet.NetStandard.csproj", "{AAB983A1-6080-449D-95D8-7E7BA05DDFAA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MySqlDataSample", "sample\MySqlDataSample\MySqlDataSample.csproj", "{346D3A9A-1296-4915-BB6C-8533731D3B3B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqliteSample", "sample\SqliteSample\SqliteSample.csproj", "{F72182DC-A933-4C4B-8321-830D0DFB857C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OracleManagedDataAccessSample", "sample\OracleManagedDataAccessSample\OracleManagedDataAccessSample.csproj", "{FFA9A7E4-954F-47A1-A9FD-0FE07EB846C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OracleManagedDataAccessCoreSample", "sample\OracleManagedDataAccessCoreSample\OracleManagedDataAccessCoreSample.csproj", "{8CF18906-150C-4AD9-B108-2A39B31105C5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Profiler.IntegrationsGenerator", "src\Elastic.Apm.Profiler.IntegrationsGenerator\Elastic.Apm.Profiler.IntegrationsGenerator.csproj", "{B7B0104C-CADC-42E0-B08B-5187926BFF6F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elastic.Apm.Profiler.Managed.Core", "src\Elastic.Apm.Profiler.Managed.Core\Elastic.Apm.Profiler.Managed.Core.csproj", "{4E235C21-5637-4498-8335-134ACAA4884E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlClientSample", "sample\SqlClientSample\SqlClientSample.csproj", "{456A8639-FE1B-426A-9C72-5252AB4D3AD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KafkaSample", "sample\KafkaSample\KafkaSample.csproj", "{2B23487A-B340-4F5C-A49B-9B829F437A5A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -375,6 +403,62 @@ Global
{0EEA16C4-C7DF-4D90-94C2-009417D765AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0EEA16C4-C7DF-4D90-94C2-009417D765AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0EEA16C4-C7DF-4D90-94C2-009417D765AC}.Release|Any CPU.Build.0 = Release|Any CPU
{A88A3877-05D6-45B2-94E4-5C583BD6EEDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A88A3877-05D6-45B2-94E4-5C583BD6EEDC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A88A3877-05D6-45B2-94E4-5C583BD6EEDC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A88A3877-05D6-45B2-94E4-5C583BD6EEDC}.Release|Any CPU.Build.0 = Release|Any CPU
{F1DD170E-2DD8-4CBD-A2BB-C19CF0033982}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F1DD170E-2DD8-4CBD-A2BB-C19CF0033982}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F1DD170E-2DD8-4CBD-A2BB-C19CF0033982}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F1DD170E-2DD8-4CBD-A2BB-C19CF0033982}.Release|Any CPU.Build.0 = Release|Any CPU
{BA2D3FCD-C25E-4E34-9A30-BE1FB16E1841}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BA2D3FCD-C25E-4E34-9A30-BE1FB16E1841}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BA2D3FCD-C25E-4E34-9A30-BE1FB16E1841}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BA2D3FCD-C25E-4E34-9A30-BE1FB16E1841}.Release|Any CPU.Build.0 = Release|Any CPU
{4983083A-87AD-496E-B0BC-84C8097D0590}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4983083A-87AD-496E-B0BC-84C8097D0590}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4983083A-87AD-496E-B0BC-84C8097D0590}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4983083A-87AD-496E-B0BC-84C8097D0590}.Release|Any CPU.Build.0 = Release|Any CPU
{14BEE605-6180-4B9E-87F5-A24BA79461B5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14BEE605-6180-4B9E-87F5-A24BA79461B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14BEE605-6180-4B9E-87F5-A24BA79461B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14BEE605-6180-4B9E-87F5-A24BA79461B5}.Release|Any CPU.Build.0 = Release|Any CPU
{AAB983A1-6080-449D-95D8-7E7BA05DDFAA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AAB983A1-6080-449D-95D8-7E7BA05DDFAA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AAB983A1-6080-449D-95D8-7E7BA05DDFAA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AAB983A1-6080-449D-95D8-7E7BA05DDFAA}.Release|Any CPU.Build.0 = Release|Any CPU
{346D3A9A-1296-4915-BB6C-8533731D3B3B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{346D3A9A-1296-4915-BB6C-8533731D3B3B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{346D3A9A-1296-4915-BB6C-8533731D3B3B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{346D3A9A-1296-4915-BB6C-8533731D3B3B}.Release|Any CPU.Build.0 = Release|Any CPU
{F72182DC-A933-4C4B-8321-830D0DFB857C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F72182DC-A933-4C4B-8321-830D0DFB857C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F72182DC-A933-4C4B-8321-830D0DFB857C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F72182DC-A933-4C4B-8321-830D0DFB857C}.Release|Any CPU.Build.0 = Release|Any CPU
{FFA9A7E4-954F-47A1-A9FD-0FE07EB846C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FFA9A7E4-954F-47A1-A9FD-0FE07EB846C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FFA9A7E4-954F-47A1-A9FD-0FE07EB846C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FFA9A7E4-954F-47A1-A9FD-0FE07EB846C6}.Release|Any CPU.Build.0 = Release|Any CPU
{8CF18906-150C-4AD9-B108-2A39B31105C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8CF18906-150C-4AD9-B108-2A39B31105C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8CF18906-150C-4AD9-B108-2A39B31105C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8CF18906-150C-4AD9-B108-2A39B31105C5}.Release|Any CPU.Build.0 = Release|Any CPU
{B7B0104C-CADC-42E0-B08B-5187926BFF6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7B0104C-CADC-42E0-B08B-5187926BFF6F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7B0104C-CADC-42E0-B08B-5187926BFF6F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7B0104C-CADC-42E0-B08B-5187926BFF6F}.Release|Any CPU.Build.0 = Release|Any CPU
{4E235C21-5637-4498-8335-134ACAA4884E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4E235C21-5637-4498-8335-134ACAA4884E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4E235C21-5637-4498-8335-134ACAA4884E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4E235C21-5637-4498-8335-134ACAA4884E}.Release|Any CPU.Build.0 = Release|Any CPU
{456A8639-FE1B-426A-9C72-5252AB4D3AD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{456A8639-FE1B-426A-9C72-5252AB4D3AD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{456A8639-FE1B-426A-9C72-5252AB4D3AD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{456A8639-FE1B-426A-9C72-5252AB4D3AD5}.Release|Any CPU.Build.0 = Release|Any CPU
{2B23487A-B340-4F5C-A49B-9B829F437A5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B23487A-B340-4F5C-A49B-9B829F437A5A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B23487A-B340-4F5C-A49B-9B829F437A5A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B23487A-B340-4F5C-A49B-9B829F437A5A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -435,6 +519,20 @@ Global
{FB07C133-C353-4061-A308-B9A6EF48AB7E} = {267A241E-571F-458F-B04C-B6C4DE79E735}
{FC0276AB-9063-4DB9-9078-DCEF1F1091A9} = {3734A52F-2222-454B-BF58-1BA5C1F29D77}
{0EEA16C4-C7DF-4D90-94C2-009417D765AC} = {267A241E-571F-458F-B04C-B6C4DE79E735}
{A88A3877-05D6-45B2-94E4-5C583BD6EEDC} = {3734A52F-2222-454B-BF58-1BA5C1F29D77}
{F1DD170E-2DD8-4CBD-A2BB-C19CF0033982} = {3734A52F-2222-454B-BF58-1BA5C1F29D77}
{BA2D3FCD-C25E-4E34-9A30-BE1FB16E1841} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{4983083A-87AD-496E-B0BC-84C8097D0590} = {267A241E-571F-458F-B04C-B6C4DE79E735}
{14BEE605-6180-4B9E-87F5-A24BA79461B5} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{AAB983A1-6080-449D-95D8-7E7BA05DDFAA} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{346D3A9A-1296-4915-BB6C-8533731D3B3B} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{F72182DC-A933-4C4B-8321-830D0DFB857C} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{FFA9A7E4-954F-47A1-A9FD-0FE07EB846C6} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{8CF18906-150C-4AD9-B108-2A39B31105C5} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{B7B0104C-CADC-42E0-B08B-5187926BFF6F} = {3734A52F-2222-454B-BF58-1BA5C1F29D77}
{4E235C21-5637-4498-8335-134ACAA4884E} = {3734A52F-2222-454B-BF58-1BA5C1F29D77}
{456A8639-FE1B-426A-9C72-5252AB4D3AD5} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
{2B23487A-B340-4F5C-A49B-9B829F437A5A} = {3C791D9C-6F19-4F46-B367-2EC0F818762D}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {69E02FD9-C9DE-412C-AB6B-5B8BECC6BFA5}
Expand Down
Loading

0 comments on commit bab7761

Please sign in to comment.