diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a062a0949..42266fb0e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,4 +65,4 @@ We're always happy to help contributors with their pull requests. ## Final word -Many thanks to all of our contributors, and looking forward to seeing you on Github! :tada: +Many thanks to all of our contributors, and looking forward to seeing you on Github! diff --git a/Readme.md b/Readme.md index 59259a20e..6f04aa16b 100644 --- a/Readme.md +++ b/Readme.md @@ -1,56 +1,99 @@ # ddprof -The Datadog Native Profiler for Linux +The Datadog Native Profiler for Linux. ## Overview -`ddprof` is a commandline utility for engaging kernel-mediated telemetry of an application and forwarding the resulting information to the Datadog backend. In several ways, it's similar to the `perf record` tool. +`ddprof` is a command-line utility to gather profiling data. After install you will continuously see where your application is spending CPU and memory allocations. +The data will be available in the `/profiling` section of the [Datadog UI](https://app.datadoghq.com/). ## Quick Start Our official documentation is available [here](https://docs.datadoghq.com/profiler/enabling/ddprof/?tab=environmentvariables). +Our pre-built binaries are compatible with both musl and glibc. You should not need to recompile `ddprof` from source. -### From binary +### From binary [Recommended] -Check out our Release page for prebuilt binaries. Download the desired binary, making sure to mark it executable `chmod +x ./ddprof`. -Refer to [commands](docs/Commands.md) for the commands supported by `ddprof`. Example : +An installation guide is available [here](https://docs.datadoghq.com/profiler/enabling/ddprof/?tab=environmentvariables). +Check out our Release page for our [latest](https://github.com/DataDog/ddprof/releases/tag/latest) release. Download the release and extract `ddprof`. +Instrumenting your application should be as simple as adding `ddprof` in front of your usual command line. + +To install the profiler, check out our [installation-helpers](#Installation-helpers) bellow. + +The following command will run `ddprof` with the default settings (CPU and allocations) ```bash -./ddprof -S my_native_service ./run.sh +ddprof -S service_name_for_my_program ./my_program arg1 arg2 ``` +Profiling data shows up in the `/profiling` section of your Datadog UI. Specifying a service name will help you select your profiling data. +Refer to [commands](docs/Commands.md) for a more advanced usage of `ddprof`. + ### From source Checkout our build section [here](./docs/Build.md). -### Prerequisites +## Prerequisites -The Datadog Native Profiler for Linux has only been tested on kernel 4.15 above. It may be supported by older kernels, but your mileage may vary. One can verify the kernel version by running `uname`: +### Perf event paranoid + +The target machine must have `perf_event_paranoid` set to 2 or lower. ```bash -uname -r +# needs to be less than or equal to 2 +cat /proc/sys/kernel/perf_event_paranoid ``` -In addition, the target machine must have `perf_event_paranoid` set to 2 or lower OR `CAP_SYS_ADMIN` enabled. +Here is an example adding a startup configuration to your system. This requires a system restart. ```bash -# needs to be less than or equal to 2 -cat /proc/sys/kernel/perf_event_paranoid +sudo sh -c 'echo kernel.perf_event_paranoid=2 > /etc/sysctl.d/perf_event_paranoid_2.conf' ``` +Alternatively you can use `CAP_SYS_ADMIN` or `sudo` as a one off test mechanism, more in the [Troubleshooting](./docs/Troubleshooting.md) section. Don't hesitate to [reach-out](#Reaching-out) if you are not able to use our profiler! +### Agent installation + +It is recommended to have an agent setup on the system you are profiling. +By default the profiler will target `localhost:8126` (the default trace agent endpoint). The `DD_TRACE_AGENT_URL` environment variable can be used to override this setting. + +## Installation helpers + +### Ubuntu / Debian + +The following commands will download and install `ddprof` on Debian or Ubuntu distributions: + +```bash +export ARCH=$(dpkg --print-architecture) # ARCH should hold amd64 or arm64 +# ddprof requires xz-utils to uncompress the archive +sudo apt-get update && \ +sudo DEBIAN_FRONTEND=noninteractive apt-get install -y xz-utils curl jq && \ +tag_name=$(curl -s https://api.github.com/repos/DataDog/ddprof/releases/latest | jq -r '.tag_name[1:]') && \ +url_release="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/DataDog/ddprof/releases/download/v${tag_name}/ddprof-${tag_name}-${ARCH}-linux.tar.xz" && \ +curl -L -o ddprof-${ARCH}-linux.tar.xz ${url_release} && \ +tar xvf ddprof-${ARCH}-linux.tar.xz && \ +sudo mv ddprof/bin/ddprof /usr/local/bin && \ +rm -Rf ddprof-amd64-linux.tar.xz ./ddprof && \ +ddprof --version +``` + ## Key Features ### Simplicity -`ddprof` is a wrapper, so using it should be as simple as injecting the binary into your container and wrapping your `run.sh` (or whatever) in it. `ddprof` will use environment variables if they are available, overriding them with commandline parameters if given. +`ddprof` is a wrapper, so using it should be as simple as injecting the binary into your container and wrapping your entrypoint. +`ddprof` will use environment variables if they are available, overriding them with commandline parameters if given. ### Safety - Minimal interference to execution of instrumented processes - `ddprof`'s Memory usage is sandboxed +### Allocation profiling + +- By working in user space, `ddprof` can instrument allocations with low overhead + ## Docs Architectural showpieces and such will always be available in the `docs/` folder. @@ -58,6 +101,7 @@ Architectural showpieces and such will always be available in the `docs/` folder - [Build](./docs/Build.md) - [Design](./docs/Design.md) - [Automatically updated list of commads](./docs/Commands.md) +- [Troubleshooting](./docs/Troubleshooting.md) ## Reaching-out diff --git a/changelog b/changelog index ecaa27f3e..0c56de040 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,8 @@ +0.10.1 to 0.11.0 (13/03/2023) +* JITDump support +* Fix crash when using custom stack (example: Fibers) +* Fix tag validation + 0.9.3 to 0.10.1 (14/11/2022) * Allocation profiling - instrument forks * Universal binary - remove dependency on libc diff --git a/docs/Build.md b/docs/Build.md index 92701b3a2..4865357c8 100644 --- a/docs/Build.md +++ b/docs/Build.md @@ -1,9 +1,11 @@ # ddprof build +We do not recommend for users to recompile the application. The pre-built binaries should be compatible with your system. +Checkout the release page for our latest builds. + ## Environment setup -ddprof is meant to build on Linux. -*Local builds on macos do not work (you don't have access to perf events).* +The dockerized environment will take care of installing all the dependencies. ### Native linux @@ -13,6 +15,7 @@ Once all dependencies are installed, you can run the [Build Commands section](#b ### Docker The [Dockerfile](../app/base-env/Dockerfile) contains all necessary dependencies to build the project. +Here is a script that mounts the `ddprof` folder within the build container. ``` ./tools/launch_local_build.sh @@ -20,7 +23,6 @@ The [Dockerfile](../app/base-env/Dockerfile) contains all necessary dependencies Once inside the container, you can run the [Build Commands section](#build-commands). - ## Build commands ### Building the native profiler @@ -32,56 +34,3 @@ MkBuildDir Rel RelCMake ../ make -j 4 . ``` - -### Building the benchmark (collatz) - -A bench application will be built by default. Following CMake flag controls the build decision: `-DBUILD_BENCHMARKS=ON`. - -## Speeding up builds - -### Bypassing the use of shared docker volumes on MacOS - -Docker can be used if you are not already on a linux environment. You need an ssh configuration as some repositories are private. -The following script create a docker container based on CI dockerfiles. It will: - -- Use your ssh configuration -- Automatically pull down all dependencies (same as in CI) -- Sync your files with the docker environment - -```bash -./tools/launch_local_build.sh -``` - -To speed up builds, we recommend usage of docker-sync (shared filesystems are very slow). - -1 - create a docker-sync.yml file in the root of the repo. - -```yml -version: "2" -syncs: - ddprof-sync: - sync_strategy: "native_osx" - src: "./" - host_disk_mount_mode: "cached" -``` - -2 - Then create a docker volume and launch docker-sync - -```bash -docker volume create ddprof-sync -docker-sync start # launchs a watcher that syncs the files (takes a long time on first run) -``` - -3 - Use the docker build environment as usual (it will pick up the docker volume from the docker-sync file) - -```bash -./tools/launch_local_build.sh -``` - -4 - You can stop and clean these volumes after usage - -```bash -docker-sync stop -docker-sync clean -docker volume rm ddprof-sync -``` \ No newline at end of file diff --git a/docs/Design.md b/docs/Design.md index 01923f252..8b3f1e09d 100644 --- a/docs/Design.md +++ b/docs/Design.md @@ -1,91 +1,10 @@ # Design -Design discussions. +Overview of the `ddprof` architecture ## Architecture -Roughly speaking, the profiler performs the following operations in sequence. +`ddprof` is a sample based profiler. It uses a mix of user space instrumentation and kernel APIs. +`ddprof` runs in a separate process and processes events through shared ring buffers. -* Instantiated by OS -* Processes options, environment variables, etc -* Initializes global objects and memory -* Creates a pipe (two linked sockets), setting the socket type to be a Unix - Domain Socket. This will be used for transferring file descriptors -* Sets up a pthreads barrier in a shared-memory region, with a shared - disposition (otherwise pthreads fails to use it properly) for coordination -* Calls fork() to create a child -* The child calls fork() and dies -* The original process iteratively calls `perf_event_open()` and sends the - resulting file descriptor to the grandchild using a unix domain socket, then - enters the pthread barrier. Iteration is done for each watcher, on each - CPU, since the `perf_event_open()` context is restricted. -* Grandchild receives the file descriptors, clears the thread barrier -* Original process closes the file descriptor and repeats until all watchers - have been enabled on all CPUs. -* Both processes close their unix domain sockets -* Grandchild creates one mmap() region to receive the `perf_event_open()` - ringbuffer -* Original process calls `execvp()` to become the target process with args -* Grandchild `poll()`s on received file descriptors to listen for events in - ringbuffer - -## Overview - -![img_fork_strategy](ddprof_archi_20210830.svg) - -### Notes - -* the grandchild does not read from stdio, so it should not be necessary to - close any of the underlying streams. But we could once we have better - logging facilities. -* We don't do anything to set the signal disposition of the grandchild or - original process. -* We should, but do not, do any resource isolation or limiting yet. - -## Architecture painpoints - -### Instrumentation Sequence - -**Problem** -ddprof needs to enable instrumentation for the process it wraps. If this -fails, we want the target process to get launched anyway. It would also -be great if instrumentation happened after the profiler gets launched -(i.e., don't profile the profiler in the common case). Basically, we'd -like to: - -* Minimize the permissions escalations required to instrument an application -* Ensure that hierarchical resource sandboxing interfaces, such as cgroups, - can be easily used in a large number of kernel versions to clamp ddprof - (i.e., don't rely on cool new cgroups v2 kernel v5.bignum features) -* Have an instrumentation sequence that could allow profiles to be collected - in a separate container entirely -* Suppress SIGCHLD in instrumented application if the profiler dies (SIGCHLD - can be used as a job control mechanism; we don't want to interfere, but - sometimes we can't help dying) -* A higher-order executor (for example, `strace ddprof app`) must receive the - PID of the _application_ and not the PID of ddprof through fork(). In other - words, the PID of the process must be the PID of the service, not the wrapper -* Isolate the instrumented application from hierarchical limits (e.g., - those in `getrlimit()` - -Of these goals, the first five are satisfied in the current implementation of -ddprof, with the last one being tricky to implement on containerized -environments without breaking containerization. We'll provide a discussion on -an alternative mechanism (option 3 above) which gets over this hurdle for -`perf_event_open()`-facilitated instrumentation. - -## Ideas - -### Alternative timing mode - -For a variety of reasons, we thought of launching with `perf_event_open()`. We could also measure time using the standard `set_itimer()` approach. There are a few unfortunate consequences to this: - -* itimers are mediated through Unix signals, which steal execution from the instrumented process (adds latency) -* signals have more skid than the kernel code, sometimes by a truly significant margin -* signals can interrupt syscalls, which can break client code -* signals don't follow forks -* have to implement new message passing system to bring samples up from children -* signal delivery is non-uniform through a thread pool--this isn't an academic point, sampling hugely favors the earliest-spawned thread -* users can over-write signal handlers - -Some of this can be controlled for by implementing an LD_PRELOAD-type trick inside of a wrapper, which could catch `fork()` calls into libc and implement some other niceties, but I'm not sure how much effort this will be to support both glibc/musl across the major versions we have to support. +![wrapper_architecture.png](wrapper_architecture.png) diff --git a/docs/Troubleshooting.md b/docs/Troubleshooting.md index 3907f2b30..15eeac7da 100644 --- a/docs/Troubleshooting.md +++ b/docs/Troubleshooting.md @@ -3,6 +3,14 @@ ## ddprof errors +### Enabling debug logs + +You can increase the log level of the profiler with the `-l` option + +```bash +./ddprof -l debug my_program +``` + ### Failures to instrument ```bash @@ -16,6 +24,12 @@ In order to instrument the system or target application, ddprof must call `mmap( - increasing the pinned memory limits - running fewer `ddprof` instances in parallel +In container environments, you can troubleshoot these issues by adding capabilities to your container. `CAP_SYS_ADMIN` (or `CAP_PERFMON` on newer kernels). + +```bash +docker run --cap-add CAP_PERFMON my_docker_img +``` + ## Reaching the agent host It is useful to verify that the target machine can connect to a Datadog agent. Follow the Datadog troubleshooting guidelines. @@ -83,3 +97,52 @@ run Example of issue: A symbol is missing from the libc (compared to the musl libc where the library was compiled) + +## Speeding up builds on macOS + +### Bypassing the use of shared docker volumes on macOS + +Docker can be used if you are not already on a linux environment. You need an ssh configuration as some repositories are private. +The following script create a docker container based on CI dockerfiles. It will: + +- Use your ssh configuration +- Automatically pull down all dependencies (same as in CI) +- Sync your files with the docker environment + +```bash +./tools/launch_local_build.sh +``` + +To speed up builds, we recommend usage of docker-sync (shared filesystems are very slow). + +1 - create a docker-sync.yml file in the root of the repo. + +```yml +version: "2" +syncs: + ddprof-sync: + sync_strategy: "native_osx" + src: "./" + host_disk_mount_mode: "cached" +``` + +2 - Then create a docker volume and launch docker-sync + +```bash +docker volume create ddprof-sync +docker-sync start # launchs a watcher that syncs the files (takes a long time on first run) +``` + +3 - Use the docker build environment as usual (it will pick up the docker volume from the docker-sync file) + +```bash +./tools/launch_local_build.sh +``` + +4 - You can stop and clean these volumes after usage + +```bash +docker-sync stop +docker-sync clean +docker volume rm ddprof-sync +``` \ No newline at end of file diff --git a/docs/ddprof_archi_20210830.svg b/docs/ddprof_archi_20210830.svg deleted file mode 100644 index 90a1564aa..000000000 --- a/docs/ddprof_archi_20210830.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO19WVdcImuW9n39XG5W9k1/6yui3nmoO1x1MDAwNFx1MDAwNVJFXHUwMDE0XHUwMDE1tbOXXHUwMDBimZVJXGJcdTAwMTCsVf+9947MlICIQEDCJE9lXFycQVx1MDAwMlxmeffwPHv8199cdTAwMTKJL+5sUP/yz8SX+rRa6bRrw8rLl7/jzyf14ajd78FLzPv/UX88rHp3tlxcdzD65z/+MX+HU+13v7+r3ql36z13XHUwMDA09/1cdTAwMGb8f1wi8S/vn77f02n36t693k/nv4VTtfzTQr/n/UZGudXMUGrf7miPMvCr3Hpccl5uVDqj+vxcdTAwMTX80Vx1MDAxN9VrXTz0z3OkSFx1MDAwNqXWwdFB+XLan//aRrvTKbmzzve/p1JtjYe+h1x1MDAxYbnD/lO93K65LXidLv387X2jPvz183dccvvjZqtXXHUwMDFmjVx1MDAxNt7TXHUwMDFmVKptd4Y/I+Ttp5Ve0/uM+U+meFx1MDAwN9ziXGJKmZVaXHUwMDFiKal4e1x1MDAxOT8gyah1XHUwMDE4JVIpy6wghrKlR0v3O/0hPtp/XHUwMDEx75o/3EOl+tSEJ+zV3u5xh5XeaFBcdTAwMTnCcc3ve/nxR3NHMFx1MDAwMVx1MDAwZqFcdLGWXHRq5dstrXq72XLxWJRwmFwiXFwrKonkfH5+o7p3MJRJbYQgav5cbj7DIF/z5ON/l7/YVmU4+PFcdTAwMDV+8Z7V9/z4v4ffhSvk7ZWhe9Du1dq9JrzSXHUwMDFidzpvr9V7tYhXOpWRm+53u21cdTAwMTfEqNhv99zlO7zPTVxyh/2XVr1SXHUwMDBi+eTI11x1MDAwNvhxcyXAa/5fifmxe//z9t//+/fQu5PRh4FX4Fx1MDAxOOaf9zf/v//993CFXHUwMDFj1qvud3lcZtFKakmUVlJlXHUwMDE4MZZJsrZWNqblq1HpvnXxdNK7LmeyjYfLg/TeayUh1OGaSW6EXHUwMDE0nDO9pJVaONwqZpUl1mhldGxaXHQn74BcdTAwMTBw0CqqLfymXHUwMDEwrZTSXHUwMDExglOtmLKSg1xuXHUwMDA2tFJcdTAwMWGpmbWGba6VI/yflVr5JnxfzthD4VxcZt2jYSZf1cXjnjnmuS9riaRbn7qh0sh1lDRcdTAwMWHKKVx1MDAxN1xcru9cIq7r+dJw9HianNVcdTAwMDdXXHUwMDE3XHUwMDAzm5pcdTAwMTZcbnr/hVFxR1pOXHKRXHUwMDAyhEAtu1xiqVx1MDAxZNBLzYWxXHUwMDA2Tnr5yXYni4pcdTAwMDVlLyhsjFBcdTAwMDbuTEhcdTAwMTOHsM3f3uj33FL71UNcdTAwMGJk4adHlW67M1v4wj3xgl9Qq1xyhv2G/ytcdTAwMTjVPXhcdTAwMDI3m4W7U512s+ehl3pjUTLdNoCgt5fd/uDLSsmuoMdcYlx1MDAxNW1cdTAwMTVcdH9Ah+GkjLZ8bdku9ljjoNl5Llx1MDAxY1HRXHUwMDE11+2zr6Lc2H/ZtspRklx1MDAxMkGNZpwsw1x1MDAxZitcdTAwMWNtwexZXHUwMDEwb1x1MDAxNG1cdTAwMWWbbFM06ZJcdTAwMTPUI1x1MDAxZWZkqUNArIVl1G+Df8g8+mCj9Db29bdDPctcdTAwMDK9U+BcdTAwMTNxXGbeS/5cdTAwMDPYXHUwMDEw8ER6XHUwMDE3XHUwMDE2rYKcKW4sXHUwMDExem1cdTAwMTU8KYnu7fNhKpvMPlx1MDAxZJRkeZArTGZ7r4JUMYcoXHUwMDAzXHUwMDE30Fx1MDAwZmvsolx1MDAwNlJcdTAwMDbOR1x1MDAwMP4gXGJ4iIxNXHUwMDAxuVxy6lxc0Llwg1x1MDAxY8hPk/bHtzT6w6dP9SwrYTzn0TCeXGLA8YBcdTAwMTbl2qL9etT9Wi7a0mUpl8vfnZ6ejpVu779oW+2AXFxbqSylfFx1MDAxOThcdTAwMDGUclx1MDAxNFx1MDAxMSjXWlLg4FwiNuGmgjpcdTAwMWF+n4Sn0Gi/VFDYXHUwMDA1wDgllbCCXHUwMDAyf2bCLss+hT+FM0JULCh+O1x1MDAwM8pcdTAwMDSPlDJKXHUwMDE4XHUwMDA3r27WN6BtNzNtk0zpTEzMIzstcXNWvth7KVx1MDAwM6zmXHUwMDAwUVx1MDAxNGAlgVxyXHUwMDA2MFxm2leG8lx1MDAwN5dUMs5cdTAwMTCOoEGxXG5hg1RcbvSvXCJcdTAwMWU5+phcdTAwMTGtttqd2qda0ajopPKhuWXmyUFJlTXr289ZQVx1MDAxZjOtU51M77J7n/56KJOvo/2XbE1cdTAwMWNcdTAwMDLGk0mlQuwnU1x1MDAwMFxyhFx1MDAwNq4nJOE8RnROXHUwMDFjzcBnaeBETClBWIig4+MosI5cdTAwMTYuJf0m9qfcXHUwMDBieL+mgv0noPT4YpPRZ4FX4Fx1MDAxNDZE6pFsmdlIT6M1WlWh6drqWH6qmXNOTi9TtdvinTiZtu9cdTAwMWH7XHUwMDFmlWSaOsxcYsOFolx1MDAxYUDwojpcdTAwMDLEkJJcdTAwMDBusNJaOFwirWJTR1x1MDAwZs4ocPDwnUtrXGZcdTAwMTFBdSRcdTAwMGVjWkhcdTAwMDA0lFOipGTL+lxiUMhcbmV8weS/rjrGS5ojj1x1MDAwM69k8CQ21MnVPENHU2jBuOXc0PVcdTAwMTHgoFtcdTAwMTT6cNZVZTfv1vJjN1m0fO9cdTAwMTWTS6TQ4CZB6ZhlXHUwMDAxR8mFXHUwMDAz9NkwSjCaZXSMRFx1MDAwM+g62Fx00CpcdKqlwVx1MDAxOFx1MDAwNDVTXHUwMDFhh1x1MDAxYThcdTAwMTdKvt9jllx1MDAxNVx1MDAxM1x1MDAxYyVcdTAwMDNOxO1cdTAwMTaa+VGiXHUwMDExhca0L1x1MDAxZLkkZtYyXCIt2YDN5muX5FWcXHUwMDFldV76NZLh16VcdTAwMDfhx5B7KmWCMlx1MDAwN2BcdTAwMTgwQKJcdTAwMDHBL0uZhpPXRFGAplZcdFx1MDAxNl+khjmcgPBgXFxWMiONXHSKXHUwMDE4SJWD2TOuXHUwMDA1MZz7mfVcdTAwMGZcdTAwMTHjgkggiNtwkN/O+MeHxVwij1x1MDAwMq/AIexcZoqRyNBcdTAwMTLnoI1WmfVzcoeycPjYPLu+7Vx1MDAxNS96+UJmYi9cbmrvdZEp6yilvb82JCdHuVx1MDAwM3aVXHUwMDEyXHUwMDBliExcdTAwMTJqYkzKXHUwMDAxXHUwMDEydFx1MDAwMFx1MDAwMINbIZpg0DokSUdcdTAwMDCSXHUwMDFicE0gKuCMQSB0QFx1MDAxZq0gxHJlt1xirP52+lx1MDAxOCtcdTAwMThLRlx1MDAxZoj3/sBRbKiV26QyrCaAtK1dXyuPn1x1MDAwZnL5YvGoVD/Rz4PbVG+Ykb2910rwf1x1MDAwZZBcbouVXHUwMDFiKlx1MDAxMK/g1lx1MDAwMa9DhcBoXHUwMDA2Uz6/tfNcXEaIS1xmxuFcdTAwMTSwaKv3M1xmV5+2Xf/f/+uy5NZcdTAwMDdcdTAwMWWW5Vx1MDAxYfSIUFxmPa0t1+T+aFhrm1nmJZ36+jLJmsnVQ2HHcl2rjFr13VxutiTCMVJcdTAwMTDNiWFcdTAwMDb+a8ndKONIXHUwMDA2XHUwMDE2XHUwMDFjnFx1MDAwZVx1MDAxNt9F81x1MDAwYtngtarYXrK1drC+T0nOwe1cdTAwMDF9XGJcbjpcdTAwMDcuxKxFnMq0tDYg91x1MDAwNt5KhN9e/XE1P65ccl1N5GngXHUwMDE1OIdcclx1MDAxZM1K1i+i6Vx1MDAxOFx1MDAwNTpmuZU+S/GeVlZcdTAwMGKH+a8t8fyo70+vSEk+1r8+7To6XHUwMDFlg1ZcdTAwMDK7doywzFx1MDAwMJdcdEn8gKLC8Vil4Fx1MDAxZWrJXG5cZvhRrWTMXHUwMDAy9+PESk1cdTAwMTbq/+bBcWpcdTAwMWSgjFxcXHUwMDAx7ODWXGJcdTAwMWUg/WBJXHUwMDE1sISY3NGb7EVY4Fx1MDAwZkFcdTAwMWawi9EugnCNXHUwMDA1nOu7iN5skL2c1NtcdTAwMDNZ7GR5q0wzN6y6/8IoqXQ4XHUwMDE2XGZzXHUwMDAyzDooi8BIJGVgI1x1MDAxNKb/V4SgPiqMNCzm5P9cdTAwMDN+1kxcdM5ccjCkeIJMXHUwMDFmgz9nw0Gr0ktcZob9KvzKfya+9U7ajbrb7tZcdTAwMTO9fqLT7zXrQ/ghYKKnei3h9lx1MDAxM26rnvj+hXzr/XhXKHzyJTF2XG6folTDmijNMFx1MDAxYYCTpnr9qFl1Wry+ndF05eypWmp0O6J5+ML2XzE4YVx1MDAwZZNac+BiIWEzpTE8zkF9rOY6VlawVoVcdTAwMTNcdTAwMTXgrJFcdTAwMWHuoVrsV4VcdTAwMTNcdTAwMDDeSLOvXHUwMDE4k1x1MDAwMHy4WFu6XHUwMDA1u3u8eVx1MDAxNTdcdTAwMGYpcFx1MDAxN9X09Dxfncq9Z7yEMrDrXHUwMDAywIfiOpB50MohXHUwMDE0o8VcdTAwMTTrnKSKr/KEKuVcdTAwMDC4XHUwMDEwktClXHUwMDE2hHnaXHUwMDAxPFx1MDAxMChcdTAwMTixRnFmQrtcdTAwMTRcdTAwMDCbXHUwMDE4a7bJz2+CQNJuuXt0bVx1MDAxYifj2XO3Kdyvhb6pfVxmgehIM0tcdTAwMDF+XHUwMDE4Ylx1MDAwNV8/OT0h7a8zlklccjLlg5RVpHX/fHaz/5JcYlx1MDAxMmC5lEyBMZVmqWXGXHUwMDEyXHUwMDA0J8ZcdTAwMTBcdTAwMDLsXHUwMDAwaHt8XHUwMDE5MLlW7IVcdTAwMTKJfVxuPFx1MDAxZVn7oJk9naVcdTAwMDaDjexsXHUwMDE1fnd9uMLSdtu1XHUwMDFhnNr2xlx1MDAxNshcdTAwMGWNlHE4d0uNkutb26eD3GSQT7HupJhcdTAwMTdcdTAwMTedSTI1Oz3cP1x1MDAxOVx1MDAxN46yXHUwMDE2w/tgmsBySbko81x1MDAxY1xiOFImXCJcYtg+X1wiXHUwMDE1P49cdTAwMTnlMKu1XHUwMDAwq1x1MDAwNzZgoVly18hCXHUwMDAwxOFcdTAwMDSekCiA/34mOje/XHUwMDE0yChcdTAwMDXrKkI7XHUwMDE4qCBWw1ewRVBmXHUwMDEz25s7r7Q7w+F0+npw3jzJv/BS3c7/cLihrF77/a9cdTAwMTeXxXHFLbqWT4fdl0f/XHK14lxiXHUwMDAwUv3q9cKc88noPuu+nDD/XHL53sV4csguZXKQbryWXHUwMDA356XSmfLfII7H2XLhru/OLs9v0nepq3TxXvhvuDgqXFxk81dcdTAwMTWtWo3H3MFYXHUwMDFm9mXbf0OxVT9Lu4CF+/d3T5Nuqc5cbqUn/1xynbv+9KzyeHl1+ZgpXGafnptXpCb9N5zkZD9Veukpln1IkZtaqXBX6flvaE0yk9e720NxRI7O7rK3jydV0/yYk2I0ulbXWFx1MDAwMoab2vW91ODyrk6zJ/z5hpLxVWbWfMpkn/dPg5fJXHUwMDAwQFwijFx1MDAxOINHliRIXHUwMDA2KKeONFilK1xmo3Em0X1cdTAwMDGJuYpcdTAwMDY4MpWGM1x1MDAwZVx1MDAwZr2PblxuO+na4JiaQHm9vzJcdTAwMTHqs0RMlDeqUsRcdTAwMWZ/WFx1MDAxMnPwUHC4ZoPsdLXQ0+0jY7/Oztu9nshcclrn/HfoqpOO8LguVlx1MDAwNSxcdTAwMGZcdTAwMTVcdTAwMDBcdTAwMTlcdTAwMDenhVx1MDAxNVx1MDAwM2DxpeAxNi9jXoJQTVxmhlx1MDAxY8O66lx1MDAwNGgjPCb2lOtQTqC1XHUwMDAyXHUwMDA3+5+RLIhxnkDUSXgvLlx1MDAxZsL809byN5GpO6EjK+jhXHUwMDExXHUwMDA0XHUwMDAx07Y+YlxmZ22fpolkK020zDhcdTAwMDKIhlZIfoxdbK5cdTAwMDNcdTAwMTLicMKIXHUwMDAwIZdcdTAwMTaUNr5cdTAwMDJ6w1x1MDAxY3hcdTAwMDZcdTAwMGWOT1NlWUj7XHUwMDExd1x1MDAxOLByooFwWvQ5wZItauBZgcLtS8nWv97kXHUwMDE0PFV1jFx1MDAxZoO1rlZjYFkxyTVcIl1cdTAwMWamalZcdTAwMDb4dzhcdTAwMTK+XHRcdTAwMDaWxeuB8TV4Jt6G2eRXhIR+3PzvuKxArCnDKDnAKyBcdTAwMDFcdTAwMWLagSiHXGafXHUwMDFhiTvhWbBgXaxcdTAwMWaFzlx0VlPZ8e31WerxRJxmrtPdZnf/7YByLFx1MDAxMZZrsL9AXHUwMDE1XHUwMDE3gyNMO1ZR4G/wXUiidXyoXHUwMDEzPT+28jKL0020oiHBXHUwMDEybVx1MDAxZCaJYlx1MDAxNvtccjG1XHUwMDFjpIpcdTAwMTS4LZCFLULUf3zy21x1MDAxNX1cdTAwMTZ4XHUwMDA1TmFDZYyep1x1MDAxMl0mhnFiziVbv1xcf2Iq6YOHm9ZtnXVdXqxf9e46x3ufXHUwMDEyskhcdTAwMDKNkVRcdTAwMGJpXHUwMDE4X3LKWLnJwFx1MDAxN2v4XCKwXCIyNmX0pS9WRCo1U0hF9T52vNcnlc5cdTAwMWXlg0hkTVxuuCCg/JSuX1x1MDAwNXDfbjbHk0yz+NJcIoPHy4E+adRcdTAwMWY/UbK38zPSKHQl0lx1MDAxOFxmOy5XpEjpXHUwMDAw/SVe/1x1MDAxOKOrplZcdTAwMDF8qtvq9qLNXGJ3sC7JXG7GzWKy503UlXZcdTAwMDBPYk2KXHUwMDBlXHUwMDBiSFpAxFSQmPKgK6VsRVx1MDAwZmJ0LaLVRFqp+fpI5rR4WGxfdZ5r1fzxPVFpdfR18pn59O1EXGZsooPTxFx1MDAwMCYqsJA+NoDvN1x1MDAwMGWA5jCgk9hcdTAwMTAso63nR0VcZj7cIcCvrFx1MDAwNMhk/MNcdTAwMWLmRSfW8ZrewMlykEVcdTAwMTboQFx1MDAwNCRDiWB/Wlx1MDAxMH9cXFx1MDAxZlx1MDAwMDNRp4FXMnBcdTAwMTC7XHUwMDAyM3RFXHUwMDE1olGEWrVB4dfrmHRVoTJcdTAwMWOVT1x1MDAxZp/IXHSZ9c8rv4HJt9KB791waSiAyEWLr6SDXHUwMDExPsx0gjVeXHUwMDE16vuwOuqQvpNgQFtj06HRfFx1MDAxZtGMl3ZNuJWn+lxi67m+9Vx1MDAwNu1aot/w1XbtRXyb2Vx1MDAxNTOrOFx1MDAxMHhJ6PpOiE4y7s3RZZ1cZolLZqc5WVx1MDAxYVx1MDAxNu2+02lvbJxcdTAwMDFAx7DbdnlmXHUwMDE1sFNHoTKAR1x1MDAxNlh+XHUwMDFiX0lcdTAwMTdxJGfgQpbHws1BXHUwMDBldzAtq4Eyw0PzsLwrWkR41D9cdTAwMDHuXHUwMDBmXHUwMDA1uCNOXHUwMDAyr8BcdTAwMTls6H1Wklx1MDAwZe2zcct9yVxmNVFuQDomj+Ls/nzkXHUwMDFl3jXvr45vX29fUpefOEBuXWVcdTAwMTTeXHUwMDA0XHUwMDEw61xyZSRMWr2gnMBWXHUwMDFkxbxWXHUwMDE0qoGHLHokwYRcdTAwMDOQXHUwMDFmOFxiJ1x1MDAwNPyAji/mXHL+zlx1MDAwMbTKudRUKet7zHmsXHUwMDBi6JJcdTAwMDYjQlxit0T5R2q8JWCVpFx1MDAxNFx1MDAwN4x8PlxyiSx3j657tNpcYlwi/Fx0v/dELmOyl658XHUwMDFkZjM0nTrslDPP9Wbrd1x1MDAxMzn4XHUwMDExXHUwMDAz/aeCXHUwMDExhd3OakHkXHUwMDE4yFx1MDAwMdxcdTAwMDFcdTAwMDdccjBIc6NijK+KsHlcdTAwMGLBtD5nQsJcdTAwMWZcdTAwMTFcdTAwMGa5fTNvXHUwMDExtTI/jd7H0FKp360nKi/1XHUwMDEx/vtbz22B+1xir3mPXHUwMDAySO9cdTAwMTatbV/1voJcdTAwMTdQVHUj9PrdSaly6eZmdj0uZFx1MDAwN/pBJm9fpZqd7KOKrKxVk0Q5XG570jHoQvViXHUwMDA2glx1MDAxYeZcdTAwMDBcdTAwMDZcdTAwMDH1XHUwMDAy0aSMxKhcIjok91x1MDAxOFx1MDAxMvW0gltq4+FcdHNcdTAwMDV5t9rMvVx1MDAxOVbd48eHQfZKfVx1MDAwNdPyUKhOkv5cdTAwMWLeLWhcdTAwMWJdZCe542q1VEl1eeeuM5lkO1n/XHKP+aNak0z44EX201fudfNMjPL+XHUwMDFi6rPz/sFooJl0++nk8CgzPW9e7kiLiz9reHZbbro1ueEsWnNcdTAwMTlYVzD0XHUwMDFidPtcdTAwMWX0p8+np8mLRs5Wi1xykZlcdTAwMWXUZmb/NDdAblxixmlxXGKPXHUwMDAwrkxcdTAwMTbLSlx1MDAwMVA5XlxmXHUwMDA160qZjJPcXHUwMDA0XHUwMDE1lStcdTAwMWM0xThcdTAwMTEqJGRcdTAwMGJcdTAwMDCKMC3+1OokPjRfz3/34lx1MDAxN75L4kJ1JIpcdTAwMDS0yznhav1i0O60r65kTT7djvlZhWZuJ+3p094rmjbWMYZroo1cdDbPJLnkjiFKYDBcdTAwMWI4Qqxju1x1MDAxNHE8+Fx1MDAxYV0oR1x1MDAxY1wiuFe3XHUwMDE3XHUwMDFhR9CEYlRkm/ktcfFcdTAwMTRcdTAwMWHdfIhohGipNlx1MDAxONl4c382Mikzvlx1MDAxNJPD4Ws/X3vpuXTvRVxmeC6m+SXHKJVYXHUwMDFlrs6FXHUwMDA0XkMlNiBaP2LbOVx1MDAxNVx1MDAwZeG+YU0xXHUwMDFhTc1WQ7lij85cdTAwMWXXh736Ztnm+GBcblXRzTCEXG6tLbHrV1FM3Urr4uai1X4+TmdfXHUwMDFmz2j+rLPrzWW7TzxQo7CYjIOIXHUwMDFiQUlgdVx1MDAxOadgPjm3hlx1MDAxMCpB0mNcdTAwMWNHiqknZiSVKjTRjPNcdTAwMGW5ksD5lm75mWrGyM9W01x1MDAwZf/AlrcrXHUwMDE5elxueFx1MDAwNb7/XHJhTORISFx1MDAxNlleTDFcblx1MDAwNlx1MDAwZXv9PEj/+bnDiifjaWdKm3Taybqzh09s//2QXG4yjrO9gvVcdTAwMWVJJpQj0O9gNacyNEZcdTAwMGZDXHUwMDFkazklq1x1MDAxNuhcdTAwMTCN8Vgr1fe5oyFz6eGNgIT+7Fx1MDAwZUx8rK4w/CS815bPYENVjKyM8XcoLcekpWSI9jZIg5Tbg+TVUN+nXHUwMDBm2l3Szo2oSu0/1Fx1MDAxM1Q6TEitXHUwMDAwwVx1MDAwYrNUXHUwMDE3Q3EqOlx1MDAwZe+SXG7+XHUwMDFkpzNcdTAwMTRcdTAwMDLMrfDK37H5lIUhP1x1MDAwNylcclBcdTAwMWWEKtI/vPLnhC5ipLV0byr9f9uymMjDwCtwXGZcdTAwMWIqY1x1MDAxNO9SK2ZzYeMjl1x1MDAxYlxmfenl3Zunm9zs+LB9xcd92j6/TX3ipPwtdVFcdTAwMTLtXHUwMDE4hS1wRlx1MDAxOFx1MDAxM+jyXHUwMDE0oIxcdTAwMTIu+C5cYsBTXHUwMDEyIzRVa4W7KTg+K/eUeVxy6sPGfX1cdTAwMDKfd99cdTAwMWbUe59MwVaX/OrIgkyNhfVMb1x1MDAxMMTK3Gfo42WaXHUwMDFkX0xOO+2Ke5e+fjnde1FX3DrgYXHqnpCWssVosaVcdTAwMGWToFx1MDAwMIJcdTAwMDHFIVLHXHUwMDE3LaZCOsJcdTAwMWFcbi6OXHUwMDE4ZYhcbsmEXG4sXHUwMDFk5ZilNbhcdTAwMWJAXHUwMDA2x1x1MDAxMHNcdTAwMWNcdTAwMWQo5D6l2zmLXGaUelx1MDAxZFx1MDAxM8ZcdTAwMTK9fkNxsZNOXHUwMDFmUpK6ml67Zvj4alM5Oth/IVx1MDAxM1x1MDAxYdhcdTAwMWRcdTAwMDVcdTAwMGZmXHUwMDE4QPQlIaOEXHUwMDAyw8N9X0LgwElcdTAwMTHjnKGw1sWwSJbAIVosnoXHXHUwMDFmtKeHaEpcdTAwMTNcdTAwMGbjRsNvXHUwMDE5f23aTUVCXHUwMDA2pJdcdTAwMWHc5frhrP7d8V1x2q7Ig1muclUqpK9q9lx1MDAxM3dcdTAwMDVum1xmIMKhYCut5CHJXHUwMDAwrG+WXHUwMDE2XHUwMDA0nFxuXHUwMDAxnkXb+JrmmcOpNdpcYs3gUv4nmefhXGaO81x1MDAwNFhp4WSAT1x1MDAwNFd4XHUwMDEwLYCQsP+Iee6x7leIOFx1MDAwYrxcdTAwMDKnsCGAj95cZlxyxjRKXHUwMDFmXHUwMDE1Y8Jgu/ja+qgmyaNjOjvrfJWmeJmun9ZGvU+cYbF1aIs4XG63u1x1MDAxYlx1MDAwMDfG+EJ53lxmXHUwMDBi4a1cdTAwMTkjjDNcdTAwMDBcdTAwMGI8xp2KVHLHYlx1MDAxNSfTWlx1MDAxYs59J+Pbr4DoXXLAXHUwMDAzTHDM3Vx1MDAwN5fPcVxylENv1cf3XHUwMDAxhVxm65GnjsJZUZpyLoF4culrPP3ZI09cdTAwMWSNQUWpXHUwMDE0YjnfptjEUo/8/YCOX89cdTAwMGVcdTAwMTU97z0+lLtqcHNafFxu9sj/Neh8MlpcdTAwMTi8l0PkYEOTXHUwMDEwXHRCV0xcdTAwMThkUuCSl1xyij7DXHUwMDBmbd8tgubGsUQpwoBEXHUwMDAw2+GLXHUwMDE2gXJHUlx1MDAxY2FcIlx1MDAxNZZ7x2hcdTAwMTHoWo27uNbecP9cdTAwMTj0WErYwq37T2H7XHUwMDE4Un1cdTAwMTm23XrCo/6fXGZUo/TA0Eg9XHUwMDAwXCKsXHUwMDE09Vx1MDAwZqZ/T1xyXHUwMDFl0qXcS2uaaaZcdTAwMGUy6nU4md3Th09cXMq6LVx1MDAxNyPGXHUwMDExRoJcdTAwMGUoytB8L6pcdTAwMDHDJl8qXHUwMDA1iJ9cdTAwMDBVYfHFtlSIJ1xm1jozy4kx28yKiJ2IXYDL+NZbQcQ+v3KZsuikJsPWOVx1MDAwMnZufUOvXHUwMDFms4Oa6Vx1MDAwZpLtUlU387ezm1nucv8kXFw5zFx1MDAxMG+PXHUwMDA1qrD0tYx4XHUwMDEyb1x1MDAwNeBs3KVcdTAwMDRcdTAwMTKvrU/sPIHX1MFvxdtuXHSmX8RYpVx1MDAxNZpMXHRcdTAwMDaxNEOkZ+NcdTAwMTnZMLf84cXLKy0/5lx1MDAwNlx1MDAwMU4rqaxcdTAwMDFaY9fVlJbrXHUwMDBlXHUwMDEy9emgP4xwXHUwMDA0Ni5FieZIflxutKQpQmJDLNHrK8rqqaJ7oyhLrlx1MDAwMC7HWK7AxoJiiGWOJHFpXHUwMDEwXHUwMDAzekRcdTAwMDCuqlx1MDAxOPdcdTAwMDFcdTAwMTOHXHUwMDEwqVxmXHUwMDA19ZWEIVx1MDAwNFx1MDAwZV1Cx3BlNFBb+MuMXHUwMDE1wVx1MDAwNd1cdTAwMWE+XHUwMDAxXHUwMDFj+DZdMTunSIDeKVx1MDAxYSOqXHUwMDE1XHUwMDEwJOvb4faDXCKBn1x1MDAxNVx1MDAxNL53bCVcdTAwMDGYp3gkRerW1Z1J6qw6vqpeP8/YTe4ld/9cdTAwMGVFXG6fbSZcdTAwMDRTmNvHbiZGjFxmPFx1MDAxNPVWXHUwMDFkKOxcdTAwMDLGMDqdXHUwMDA34ZdcdTAwMWYqvO8r8FC/XHUwMDEzO1shhd9fXpa/+Vx1MDAwN/7N/++Nh7+zyPUzwljFjNqgZaEya/ZcdTAwMGI181xcmJyW+W1JtPVDdf/rkFx1MDAxONFcdTAwMGXmn1x1MDAwNE5cdTAwMDJcdTAwMDdfvmSIOHdcdTAwMTRcdTAwMTPW4PY9wKQxemi71vR3XGbDaGX2cqpus+4mai+VYVx1MDAwM9fKjHsv7Vx1MDAwNbv2K5NcdTAwMDRSRFx1MDAwZdbFJVx1MDAxM0Qzw9YnX9PbNG2UXHUwMDBmn1x1MDAwZXL9XHUwMDA2n42Sapg/3/Wm71iKXqXDNOdWY2/3YlxiwjDl4Fx1MDAxZVx1MDAwNICpylxiJeLLXHUwMDExXHUwMDEwXHUwMDA3XHUwMDA3NDJwO1pjUZGWIUlcdTAwMDLmXHUwMDE1JGH5XHUwMDFmrtXQQX9LJZhDLqX8kyT4mN+JPFxmvFx1MDAwMsewI7fDSHRccjpTXHUwMDE0s1hcdTAwMWJcdTAwMTQ/XGbSXHUwMDE3k+fT62ZPPYlGNjvJNV9cbrveelx1MDAxNoPfUczB1Vx1MDAwYlpT8C2AdFx1MDAxN/QxKYA4onxcdTAwMWKJqzFcdTAwMDWJcyl6mOfhwcS0MYDUjdym2Hxb12NcdTAwMTZ+usL1ZOu9+rDSSdRqONo9UauP0GWEOVx1MDAxZt9cdTAwMTf5meU+3EZvMFx1MDAwMMZtOKV8/b5u0z9cdTAwMTm53f5rf5p7zFx1MDAxZdy60+RdJ7/3XHUwMDFlSEvpWOzUkdbbZLxYZ5pk2DyqqabeXGY2aqLHa3x44pOiXHUwMDBlODorOGA+jvGOoFx1MDAwMlxijqaPMWuN18HIXHUwMDAzPohcdTAwMTGugKpoXHUwMDEz8+KRM/ZQOJdZ92iYyVd18bhnjnluvX1cdTAwMWGRIVxixVwiLTDDcb6SMd+f9Z44hj/hvoujpdbRknOQNYUjtZc63JhcIo5cdTAwMTb4PVx1MDAxMFxy3J5HXHUwMDFi4I+Ko1x1MDAwMXpstFwiuIqVXHUwMDAz91x1MDAwYjHHXHUwMDE0h4ggZafwT8KlXHUwMDBlkUbBlZWfXflcdTAwMWPC9oGtglx1MDAxYaNiXHUwMDEwqbVcdTAwMTLMl2n8XHUwMDE5gXBcdTAwMTiAXHJcIozUhitD/GncXHUwMDA1rlx1MDAxZm7ofty8flx1MDAwMFx1MDAwMnCOYFx1MDAxYYCtNLgnXHUwMDEx08KBZ6JcdTAwMGVGYTF3jJPVge3xqIdqTMtXo9J96+LppHddzmRcdTAwMWJcdTAwMGaXXHUwMDA36d87XHUwMDAwXHUwMDExKYJ4XHUwMDA1hW9XODB6KKnCLJFRXHUwMDFijIPr8Ju7XHUwMDA38nB3q15Ts9fMw+3zaJTceyOktTfZloNcdTAwMTlcdTAwMDJ/4q+x+LH8XHUwMDE2U1x1MDAwNFxmXHUwMDA3U4J0clCZ+JyiXGKrT1xm7lLAUkll4slccoeiQFx1MDAxY8EpiLBcdTAwMDJwXHUwMDAzdsb5voN3UOFcdTAwMGY0+H06YviKXHUwMDFmqlx1MDAxN95cdTAwMTX/XGJEXHUwMDFlXZLrLb1RVq1fkivuyrprTq6T7nR2r69cdTAwMWJn+eTDrlx1MDAxZG9cdTAwMWNTQlx1MDAwMFx1MDAwN3JcdTAwMDBXQuNcdTAwMDB5voRcdTAwMDNcdTAwMDFcdTAwMDFiPybVXHUwMDA0bFx1MDAxMbhfXHUwMDE2Xz1cdTAwMDTjXHUwMDBlpVx1MDAxNKcoWLBsUoU1m4M7k9ziaC5lcPGLXHRuXHUwMDE10N62ertNye6fYMTblYw+XHLv/YFz2NBcdTAwMGJFqaRcdTAwMTCRU0lcdTAwMTmRyFx1MDAxMDapzLD3x4U7cVxcy+SJqX+9Oa7eXHUwMDE3WX3/VVJzXHUwMDAwXHUwMDAwSnuOnvtcdTAwMDNubyqJXHUwMDE4mFx1MDAxYiuR9sSokjhASGOnhURcIuiPi8xjXHUwMDEzXHUwMDAyXHUwMDE3TDBkX4RcdTAwMDJrtFx1MDAwMYVcdTAwMDQgjOSOb1x1MDAxMar4o5DzXHUwMDFioo5cdTAwMDKvwCFsqI3R2XFcdTAwMWG9XGaBXG5mXHUwMDE1XHUwMDAzwr5+XHRxpfRQK5+UXHUwMDA3N0+pq/4ka166j6Pz30BcdTAwMWaFw63FSVx1MDAwMF4+NLDsUTtcdTAwMDSUXHUwMDE1J7NcYo1j8eJzkcyh5vvWKcNcdKEhvVHAriw8i2RA6uTC3oO3ekKF+2K22Vi8W2pcbsBCS4y0ScpwoGBcYlx1MDAwYqSOXHUwMDA13mqAfVhcdTAwMDFcdTAwMDfA/OnzXHUwMDA1XHUwMDE2aHWyVvpKi8WUXHUwMDE4XHUwMDFjj8V5c9C/v/qrllx1MDAwZkdKXHUwMDAxXsmAXHUwMDAwbGhcdTAwMGJcIksmo8fF4vIzhXup1i+UXHQ/sL2zXHUwMDA0qyvKLGdcdTAwMGV2ZFx1MDAwM1x1MDAwMKLYzrOMnZVwwC5cdTAwMDCCXHUwMDEyXGZcYruMcUGmz7muqChj1FBcdTAwMTSYmEuJw638T+FcdTAwMGJjlVtcdTAwMTeUnVxy6r3EqF99qu9PQVx1MDAxOVsx1Fx0ZYhyur7HPC27rWnl6OhidvM4fVx1MDAxY13fvLw8uTvWk91vxlx1MDAwMvNkXHUwMDFjjJAogcuvuFmCsEKDXlGllZaSXHUwMDE4plfMsZBccl6riu1VQylcdTAwMDeAspJcdTAwMDJcdTAwMTeKWClD4iqKO0AsLMHsXHUwMDFmUyaAYJmgqMbbXGaR3XUwXHUwMDE3XGJcdTAwMDFAfkxDXHUwMDFhisPIXHUwMDAzLlPB164olVJyasFqychyMnatTm/Oh7Xbcubg5LDXeC5UeOev6jKTkWKA17JcdTAwMDBs6DFXXHUwMDBm9lx1MDAxN5FVXdSA81CWbzBDOvzQ9t9cdTAwMWNcdTAwMDCCxpHrXHUwMDFhg0iSL/VcdTAwMWFcdTAwMDCCXHUwMDA2P0s1Rl0loO1cdTAwMTXjpT5qXHJAlYE7S3DG3txcIlx1MDAxMcZorXakxKHRXHUwMDE2mJS/o3m+wFZcdTAwMDJcdTAwMWFV8TSFz7U13PR/XGLDWVx1MDAxZL3zRSFQkWqD9q9S2bTlzaxWKpUvZmftXHUwMDEz9+Rg+vpcdTAwMWJcYiOOa8Xh/1x1MDAwNpvvxHJ0hVNcdTAwMDcnulxuXCJwwLla0Vx1MDAxMvphYWQh0meCuyOQ7Vx1MDAxYiq3mWe2O3mLgG1cbndcXFKmhVx1MDAwMm68di7gXGZkLjGoXHUwMDBmXHUwMDEz6eJV4v/jf33roezimqSXiltt4Vx1MDAwZv67Pq10XHUwMDA3nbp30z/g553O/1x1MDAwYlx1MDAwNXk6ps1JK9aFRVx1MDAwN0WklsDI/MOr31Ojl8zdq0h1c/2Xx9mZerzMXHUwMDFkPE1K+0eFXHUwMDAy7WPEXHUwMDAxNGuZ4kDfiVpcdTAwMWHlIa3j2Vx1MDAxM2q1tsw/fHzX3MenMPN9LEGjrb+vs9xmP9ImSlRs1c/S7u2M9u/vnibdUp1cdTAwMTVK85bYRHyD/lfq6dpVw91uZZBw+996XrPmt96P8Vwi4ek69WuGNcnoQTrc4i4v7ovAvTtxPLSpYt+VXHUwMDBmQ46gdlx1MDAxNidcdTAwMDQrvah6QPBcdTAwMWSOgUrcjqRWMCuuRKOqt1c8jVNBOe5AXHUwMDAxJmf9vGleKcOEXHUwMDEzNilcdTAwMTe3JltCadyRiHe1cXW/XHUwMDE23HCSk/1U6aWnWPYhRW5qpcJdpfcxXHUwMDEwxtSKXHUwMDE0l2ZcdTAwMDZcdTAwMDNpa8uvXHUwMDFlXHUwMDBiUs0/XHUwMDE3J31bPe9+7T007npcdTAwMGZ7L7+GaFx1MDAxY7uBZc6Ui6U19twqgFx1MDAxNVx1MDAxYVfDa4v1gNG1h1x1MDAxZlx1MDAxNWFcdTAwMTFW7lx1MDAxZZBWLrlcdTAwMTRC0S1cdTAwMTJYsbd5nPT7g1Dj/Ism6UlcdTAwMTE9TJlcIlx1MDAxMrCbTI3kXHUwMDE5WZ89TVONbOv+tiFrzyxzpz5PurckXHUwMDE4wCpcdTAwMWSKNVxiknCvh3dBvKV2kFx1MDAwN3t9lsBAVHyL6yjm8JlWP8muXHJbKoZDtS3nlPwgxMvCz7Dgliz41F8+Sk9Gh1SUlNwzousjgIy6f3o6rqfaXHUwMDA3x8XS4/mlmv5cdTAwMDbwXHUwMDFiOFx1MDAxN1x1MDAwZc1nXFxj5swule3gdGYtwGhZzEpQXHUwMDFlX0YybKpYiL+3gFhcdTAwMTiOXHUwMDBi2kNcdTAwMTNa7lx1MDAwZp92PUGv267V4NhWSndkXHRMZHucwqFyRKzfjXObypRNvdc8OpSl5qs8fM5OTXb/ZVx1MDAxYsv9cf0wwSGRS6JNsVxyXG7zm4ZIi837cc6ix6XAhElcZk1ixWdINzrTXHUwMDBlls1cdTAwMTlmjcKOYFx1MDAxMzKxi8GDbjeL9E/9y9tcdTAwMTV9XHUwMDE4eFx1MDAwNY9h/nlrgfXIiZYrXHUwMDA2ZoEycsnM+lx1MDAxMy3vjium+tpcdTAwMThcdTAwMTRmo69dRpr30+vcrlx1MDAwM6YxqKNcdTAwMTS4/Vx1MDAxZNA4gFx1MDAwMGNcdTAwMTbVXHUwMDExsY5cdTAwMDL5XHUwMDA2QsdwW02ctWhEXHUwMDFhjlNcdTAwMGLBkVx1MDAxOGX8vNe/WM7gXHUwMDE2bMpcclxcllx1MDAwNiumtVJCafPJ8/P+atq44jDwXG5cdTAwMWPDhtq4olUqSlx1MDAxYpnQXHUwMDAwdyhbP/RTm1x1MDAxONG4OCxky7PjK96t1I7M2ePea6PAXG58jrlfRYGT2kV1NMzBXHUwMDE53oRQilx1MDAwYlxcVXxhV+UttWNcbp5cdTAwMDSIjlx1MDAwZUtlXHUwMDEwR4C1hlx1MDAxN71cdTAwMTJi5U9g+FJpXHUwMDA0l/p87qqW0GI0wy3hQlx1MDAxMKpcYpUhmXVKXHUwMDFjxalcdTAwMDaRVnpxNfxiXr1JRbo0qV2Mj9jL8UE+Vynn3L9sXj1SXG68d1x1MDAwN85/QzNcdTAwMTBcdTAwMTlB45FcdTAwMTDZSmU4V1x1MDAxYsw2XHUwMDBiP6/dmoFcdTAwMTiymLgmRlx1MDAxYYU7ccAn28V+SYH2l+BaJ+ElaOIzXHUwMDAzPCSmXHUwMDEwwv+U0MRqXHUwMDEyzzz+uVwihpv0n7L2MZrYXHUwMDAwmrhcdTAwMTFJ/Gj6MdJcdPLoLD6nXGKQzVx1MDAwNu3C4Vuh991cdTAwMGKCqXE4s1x1MDAwMOawmo5cdTAwMDS3kIMxV1pITmSc0Vx1MDAwZsA5oFxcXt96yKYyTlx1MDAxZMyLS5yNXHUwMDAyrkVcdTAwMDXqMTVcdTAwMTfAV1xm/eWFZV7RMG5+k1g9ho4wZJazdDiWaWPKR+HQ4ihcdTAwMDdcdTAwMTi+5361XHUwMDAzXGYtdtOCwPdqucRcdTAwMDJCX+3t/JFcdTAwMTiO9iZMKWbxrOeFl1s+0+/kei1cdTAwMWOZspqp5T2J1MFcdTAwMTEmXHUwMDE2vDIyZWKkee+juHBcYmdcdTAwMTKchVx1MDAwNC6n6UKrXHUwMDE34Fx1MDAxZVx1MDAxY1x1MDAxMmdcdTAwMDRwJtAlot/7tCRzXHUwMDE4/FLAUtRcYmCMbKlXZVkrNlx1MDAwNFx1MDAwNVunXHUwMDFmpFwiWuNcdTAwMWGKtW2jurzItp5vwEJcdTAwMGUrXHUwMDA3J3fm62h2+IlcdTAwMWSdW6dcdTAwMWawbUKAXHUwMDEye32dS1x1MDAxYijgfHGSgsXTNuAq4tyxsov0XHUwMDAzUFx1MDAwNLVcYuj2Of3AtMFcciDrZ1x1MDAxZlLj0/zAVPmsa4tcdTAwMTeH2ddcdTAwMGLy0lx1MDAxYu+/+6XUkWhcdTAwMTBcdTAwMTSmcJckXGZ4qcNcdTAwMDGjUIzWIVx1MDAxYo2Pg66XfFx1MDAwMORpXHUwMDE01TEtg/pcdTAwMTiq/FXJh+hccpzRLfHgZzSn/jFv7+ZvXHUwMDFmMlx1MDAxOU1cdTAwMWbGbdl96D+/vlx1MDAxMH7X3PVwvnhCLFxmPCHWXCLjgIXFaWDgQFx1MDAxY2Iws0Zx82mMK0NcdTAwMTRzjFJcdTAwMTg/I7gziOtcdTAwMTBxXyPGXCJwXHUwMDE5mtH70PBcdTAwMDeggIFrklx1MDAxNscqy1x1MDAxMEC3ZoylW7+s1lx1MDAwZtklP3LPL1hanIibbvIvXHUwMDFiY4lcdTAwMTRcdTAwMDPv7fFcdTAwMDVZot1cdTAwMWNcdTAwMDefzizboHEh/MR2a1x0YomygC/TXGbHXHUwMDAwXHUwMDAzpFV20Vx1MDAxNEij4dvH/Fx1MDAxZceYIY+vwS+sbSnE02HhOnb9xFKpNNfFcLP+U9o+5lx1MDAxMOEreNlsN2hscVx1MDAxNlx1MDAxM13lbVx1MDAxOTZ1+nzlu1x1MDAwM5Hu+tOzyuPl1eVjpjB8em5ekdr+z2OWWjo4ToBcdTAwMTElhLFyqdJU4nxz+Fx1MDAxYZhcdTAwMDJaaJefa5dMwjiWXHUwMDAyXHT9kXBcblx1MDAxZlxmY43m3lxcLG+PvVxmTIaBd1x1MDAwM3oh2+zG3flMNvhSpSFcdTAwMWHcslx1MDAwNG9cdTAwMTcygD3K8z1cdTAwMWTkJoN8inUnxby46EySqdnp4V/V80WeO17JkCPf0PWtWFxuYaJnVFx1MDAxYqnBXHUwMDExkFxyxl5cXDWOXHUwMDBivYNcdD1/6Fx1MDAxZFx1MDAxNltj20yXkof77/wsMVx1MDAwZYA15aVxydK+XHUwMDE0qlx1MDAxNe7pXHUwMDA1ZiXB/a1ieVx1MDAxZm6T4lxigKy1Wlxu5Y1+XHUwMDBm8YXYqE85XHUwMDA1w0xcdFx1MDAwM1x1MDAwNLms/OjCKYjQNlx1MDAwYoR2rf24XHRcdTAwMTXgLyBcXMIlXHUwMDBmomDhYF0oXHUwMDEzgIThX4pHXHUwMDBlZDw9N3n+kG9cdTAwMTSOX9ik9pR1j59q4q9qXGaS0XKAV0BcdTAwMDI2tFx1MDAwNSvDiiZ6QitcdTAwMWNcIpFcZvjK+qw4/Nj231x1MDAxY1Du4IA4XHUwMDFjXHUwMDE2Klxy44uNk1QyXFyuhPsyqMYxXHUwMDBl0WB4L5p4XHUwMDAxXHUwMDBi4IKlbZbEbFx1MDAwMpXDTf9aXHUwMDEyXHUwMDE53X5cdTAwMTi9vI4r8IWAxdYnZulmgTfHtlfSr9Xj3OnLrFd42nWJfVx1MDAxY8LIMEbDXHUwMDE0zmahNCCLcPrEaKqUXHUwMDAwfGpXbFxu+bAshs1gXG728FxuXHUwMDA1UriQl/1cdTAwMDXSXHUwMDE2Ssy2beEt1oeN/rCbqCTGI+zWXHUwMDFkvbTdaisxXHUwMDE4tvtDXFw5gp2E33rjXHUwMDExeJ3Ety+9/kO/Nvv2xbs5lN3F1cRcdTAwMWKN8Vxiie7DYoB7tNkg0tmaZCavd7eH4ohcdTAwMWOd3WVvXHUwMDFmT6qm+VvwO1xyppyBM7X+vSxeXHUwMDExXHRcdTAwMDF/Kzjuf1x1MDAwNJ9rgOnFRvAktdhcdTAwMGbGgFx1MDAwZVx0Llwi5pppXHUwMDAwRFx1MDAwMPNx5DG31EfjfmbTcVj0PrA7XHRQXHUwMDEz6Fx1MDAwMZBcdTAwMTIuJOchpWR/2Fx1MDAxZFxckYeOVzJ43lx1MDAxYlx1MDAwMrpoxY9usFx1MDAwMK4jubZcdTAwMWLofXh/6N7rvZfDXHUwMDAwKI2SKlx1MDAxOVmK6yjhcIC8oPKKLUyA3H31XHUwMDE4XHUwMDE2XHUwMDE3XHUwMDE44e2exlqBXHUwMDEwZudcdTAwMDDMo1Jpy4ArLdjkeYdcdTAwMWHFfW3sl1x1MDAxN5FiXHUwMDE5XHJ8ncA/vM4/lFpcdTAwMWSv8ofaXHUwMDFmbJKwXHUwMDE2vDmuUuCca1x1MDAxZXhcYulQLPXBQlx1MDAwMIVTd1wi9/utuXTwd7I7yUip815cclxu3IaGZyWTxGqxSNSBm2lxJNr65ud8cnaT7p+ScZOke1x1MDAwZq/56fiy9InmZ13wLlx1MDAxY4BcdTAwMTBUY0m6UcQ3lOyHOVwiXHUwMDAy61VccjA5oPVyqZdcdTAwMTF7xblcdTAwMDRur7C5U8fY70XA6Xhz/ZXAuVxcIdZIUsBL1Fx1MDAxYcBcdTAwMTn+/ORPUyRcdTAwMDFAXHUwMDEzLraxRJvA/HdniISv9PXd8O7cg3zvYjw5ZJcyOUg3XsuD81LpTPlvXHUwMDEwx+NsuXDXd2eX5zfpu9RVungv/DdcXFx1MDAxY1x1MDAxNS6y+auKVq3GY+5grFx1MDAwZvuy7b/h3eFcZqtzJon3nG9cIlxula+lxdHsW0eWmFlJtKBkXHUwMDAz/T1cdTAwMWRcdTAwMWZcXFxc9UrX57n2IDV86mWHYpTZP/jwnv5S6aBcdTAwMTNcdTAwMDbNYcbSpV1Smlx0XHUwMDA3I0JcdTAwMDCtXHUwMDE4XFxcIr6Gd71ellRLz5bEnSV9V1x03Zth1T1+fFx1MDAxOGSv1FeuxUOhOkn6b4hrVpDvhsb0cZiTN9Xe5e1hbXx7Uck1eWVHqdzisFx1MDAwZlx1MDAwMoxAJYzwf/7iUU5cIte+aSE4IXz9ur2DVPnoVPRS1m3kXHUwMDA3XHUwMDA3R0eVdIqe7Z/iXHUwMDA2WjmpIy34WVwirOF6MaOjpHZwRzX/3jXCYlx1MDAxY1e8k8Zq5lxyXHUwMDE4I386OVx1MDAxM3vcV1x1MDAxZF1cXGGiy4tcdTAwMDDsXHUwMDExq7hZv5cz3IztvTpcdTAwMWHiZVQ44FutlyZRottcdTAwMTRcdTAwMWH8XHUwMDE004wo31xu9n3rYsGkXHUwMDFi7pj79anVpTZcdTAwMTbjXHUwMDFiXHUwMDBlkYhoY5EyOrtcdTAwMWGKzX7c/Iv6WNZ8pt+Jjv/l+1j+9uM3fKlcZlx1MDAwNiW34tbf5OTLpF1/OVxiaut/NbxcdTAwMGLP9d9/+/f/XHUwMDAx0XJIiSJ9 - - - - ddprofforkchildexitOrphan process: Lifetime no longer linked to the parentprocessforkMyAppprofilingparent evalMyApp takes thepid of the parentSome awesome thingsProfilingKernelperf_event_openEvent bufferwrite eventReadbufferhttp exportget dwarf to unwindGeneral ddprof designddprof MyApp Open socketOnce per CPU + pertype of watcher(example CPU / wall)mmap toevent buffer LoopWorkerforkWorkerspawnPerform a userswitch prior to mmapusing "nobody" userProfiling \ No newline at end of file diff --git a/docs/wrapper_architecture.png b/docs/wrapper_architecture.png new file mode 100644 index 000000000..99d1560b9 Binary files /dev/null and b/docs/wrapper_architecture.png differ