Imported Upstream version 5.10.0.47

Former-commit-id: d0813289fa2d35e1f8ed77530acb4fb1df441bc0
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-01-24 17:04:36 +00:00
parent 88ff76fe28
commit e46a49ecf1
5927 changed files with 226314 additions and 129848 deletions

View File

@@ -1,73 +1,193 @@
<h1>Profiling Interface</h1>
<h1>Runtime Profiler API</h1>
<h3>Profiler Operation</h3>
<p>The profiler API can be used by dynamically loaded profiler
modules to monitor different aspects of a running program. The
API is also usable by embedders without having to compile a
profiler module.
<p>The following methods can be used by dynamic profiler
methods to monitor different aspects of the program.
<h2>Profiler Modules</h2>
<p>A custom profiler will have one public method defined in
the shared library which is the entry point that Mono calls at
startup, it has the following signature:
<p>A profiler module is simply a shared library with a single
exported function which is the entry point that Mono calls at
startup. It must have the following signature:
<pre>
void mono_profiler_startup (const char *desc)
</pre>
<pre><code class="mapi-codeblock">
void mono_profiler_startup_example (const char *desc)
</code></pre>
<p>Where "desc" is the set of arguments that were passed from
the command line. This routine will call
<tt>mono_profiler_install</tt> to activate the profiler and
will install one or more filters (one of the various
<tt>mono_profiler_install_</tt> functions).
<p>Here, the <code>example</code> portion of the function name is
the name of the profiler module. It must match the shared library
name (i.e. <code>libmono-profiler-example.so</code>). <i>desc</i>
is the set of arguments that were passed from the command line.
<p>In addition, a profiler developer will typically call
<tt>mono_profiler_set_events</tt> to register which kinds of
traces should be enabled, these can be an OR-ed combination of
the following:
<p>For example, a bare bones profiler module might look like this
(<code>example.c</code>):
<pre>
MONO_PROFILE_NONE
MONO_PROFILE_APPDOMAIN_EVENTS
MONO_PROFILE_ASSEMBLY_EVENTS
MONO_PROFILE_MODULE_EVENTS
MONO_PROFILE_CLASS_EVENTS
MONO_PROFILE_JIT_COMPILATION
MONO_PROFILE_INLINING
MONO_PROFILE_EXCEPTIONS
MONO_PROFILE_ALLOCATIONS
MONO_PROFILE_GC
MONO_PROFILE_THREADS
MONO_PROFILE_REMOTING
MONO_PROFILE_TRANSITIONS
MONO_PROFILE_ENTER_LEAVE
MONO_PROFILE_COVERAGE
MONO_PROFILE_INS_COVERAGE
MONO_PROFILE_STATISTICAL
</pre>
<pre><code class="mapi-codeblock">
#include &lt;mono/metadata/profiler.h&gt;
#include &lt;stdio.h&gt;
<p>Developers can change the set of monitored events at
runtime by calling <tt>mono_profiler_set_events</tt>.
<h4><a name="api:mono_profiler_install">mono_profiler_install</a></h4>
<h4><a name="api:mono_profiler_install_allocation">mono_profiler_install_allocation</a></h4>
<h4><a name="api:mono_profiler_install_appdomain">mono_profiler_install_appdomain</a></h4>
<h4><a name="api:mono_profiler_install_assembly">mono_profiler_install_assembly</a></h4>
<h4><a name="api:mono_profiler_install_class">mono_profiler_install_class</a></h4>
<h4><a name="api:mono_profiler_install_coverage_filter">mono_profiler_install_coverage_filter</a></h4>
<h4><a name="api:mono_profiler_install_enter_leave">mono_profiler_install_enter_leave</a></h4>
<h4><a name="api:mono_profiler_install_jit_compile">mono_profiler_install_jit_compile</a></h4>
<h4><a name="api:mono_profiler_install_module">mono_profiler_install_module</a></h4>
<h4><a name="api:mono_profiler_install_thread">mono_profiler_install_thread</a></h4>
<h4><a name="api:mono_profiler_install_transition">mono_profiler_install_transition</a></h4>
<h4><a name="api:mono_profiler_install_gc">mono_profiler_install_gc</a></h4>
<h4><a name="api:mono_profiler_install_statistical">mono_profiler_install_statistical</a></h4>
<h4><a name="api:mono_profiler_set_events">mono_profiler_set_events</a></h4>
<h4><a name="api:mono_profiler_get_events">mono_profiler_get_events</a></h4>
struct _MonoProfiler {
int dummy;
}
<h3>Coverage</h3>
static MonoProfiler profiler;
<p>To support profiling modules that need to do code coverage
analysis, the following routines is provided:
<h4><a name="api:mono_profiler_coverage_get">mono_profiler_coverage_get</a></h4>
static void
runtime_inited (MonoProfiler *prof)
{
printf ("Hello World");
}
void
mono_profiler_init_example (const char *desc)
{
MonoProfilerHandle handle = mono_profiler_create (&amp;profiler);
mono_profiler_set_runtime_initialized_callback (handle, runtime_inited);
}
</code></pre>
<p>To compile this module, a C compiler must be invoked in a
similar fashion to this, on Linux:
<pre><code class="mapi-codeblock">
gcc -fPIC -shared -o libmono-profiler-example.so example.c `pkg-config --cflags mono-2`
</code></pre>
<p>Or on OS X:
<pre><code class="mapi-codeblock">
gcc -undefined suppress -flat_namespace -o libmono-profiler-example.so example.c `pkg-config --cflags mono-2`
</code></pre>
<p>You can then load the module using:
<pre><code class="mapi-codeblock">
mono --profile=example hello.exe
</code></pre>
<p>(Note that adjusting <code>LD_LIBRARY_PATH</code> may be
necessary in order for the dynamic linker to find the module.)
<h2>Profiler Functions</h2>
<p>These are the functions usable for profiling programs.
<p>Each function has a note indicating whether they're async
safe. An async safe function can be invoked in a signal handler
or when the world is stopped by the GC. Conversely, a function
that is not async safe must not be invoked in such a context or
undefined behavior can occur (crashes, deadlocks, etc).
<p>Some functions may only be invoked from a profiler module's
init function (or prior to running managed code in the case of
embedding). This is noted explicitly only if applicable to a
function.
<h3>Basic Functions</h3>
<p>These functions are used to load and install profilers.
<h4><a name="api:mono_profiler_load">mono_profiler_load</a></h4>
<h4><a name="api:mono_profiler_create">mono_profiler_create</a></h4>
<h4><a name="api:mono_profiler_set_cleanup_callback">mono_profiler_set_cleanup_callback</a></h4>
<h3>Code Coverage</h3>
<p>These functions provide access to the JIT compiler's code
coverage support. This functionality can be used to collect
information about how many times certain code paths have been
executed.
<h4><a name="api:mono_profiler_enable_coverage">mono_profiler_enable_coverage</a></h4>
<h4><a name="api:mono_profiler_set_coverage_filter_callback">mono_profiler_set_coverage_filter_callback</a></h4>
<h4><a name="api:mono_profiler_get_coverage_data">mono_profiler_get_coverage_data</a></h4>
<h3>Statistical Sampling</h3>
<p>Statistical sampling can be used to interrupt managed threads
based on a certain mode and frequency for the purpose of
collecting data about their current work.
<p>One common use case for this functionality, usually referred
to as call sampling, is to collect a backtrace from every thread
when a sampling hit event arrives. This data can then be compiled
into a report indicating where a program spends most of its time.
<h4><a name="api:mono_profiler_enable_sampling">mono_profiler_enable_sampling</a></h4>
<h4><a name="api:mono_profiler_set_sample_mode">mono_profiler_set_sample_mode</a></h4>
<h4><a name="api:mono_profiler_get_sample_mode">mono_profiler_get_sample_mode</a></h4>
<p>A callback must be registered to receive sample hit events.
Please see the <i>Callback Registration</i> section below.
<h3>GC Allocations</h3>
<p>Profilers can be notified about all GC allocations performed
by a program or the Mono runtime.
<h4><a name="api:mono_profiler_enable_allocations">mono_profiler_enable_allocations</a></h4>
<p>A callback must be registered to receive allocation events.
Please see the <i>Callback Registration</i> section below.
<h3>Call Instrumentation</h3>
<p>The JIT compiler supports instrumenting managed method entry
and exit points so that a profiler callback will be invoked.
<p>While such callbacks by themselves have traditionally only
been useful for call count profiling and the like, Mono gives
these callbacks access to the arguments, locals, and return
value of instrumented methods (together referred to as the 'call
context'). This enables many profiling scenarios that would
otherwise have required explicit hooks in the base class
libraries.
<h4><a name="api:mono_profiler_set_call_instrumentation_filter_callback">mono_profiler_set_call_instrumentation_filter_callback</a></h4>
<h4><a name="api:mono_profiler_enable_call_context_introspection">mono_profiler_enable_call_context_introspection</a></h4>
<h4><a name="api:mono_profiler_call_context_get_this">mono_profiler_call_context_get_this</a></h4>
<h4><a name="api:mono_profiler_call_context_get_argument">mono_profiler_call_context_get_argument</a></h4>
<h4><a name="api:mono_profiler_call_context_get_local">mono_profiler_call_context_get_local</a></h4>
<h4><a name="api:mono_profiler_call_context_get_result">mono_profiler_call_context_get_result</a></h4>
<h4><a name="api:mono_profiler_call_context_free_buffer">mono_profiler_call_context_free_buffer</a></h4>
<p>Callbacks must be registered to receive method entry and exit
events. Please see the <i>Callback Registration</i> section
below.
<h3>Callback Registration</h3>
<p>In addition to the above functions, there's a large set of
functions for installing generic profiler event callbacks. These
are generated from C macros and so are not documented here.
Please refer to the <code>mono/metadata/profiler.h</code> and
<code>mono/metadata/profiler-events.h</code> headers for a full
listing of these.
<p>Callback registration functions are all async safe and can be
safely invoked from multiple threads at the same time, with the
caveat that altering a registered callback from one thread will
not immediately affect another thread that is already invoking
the current callback.
<h2>API Stability</h2>
<p>The profiler API does not have the same API stability
garantees that the rest of the Mono embedding API does. While
a breaking change to the profiler API is extremely rare, it has
happened in the past when changing the API in a backwards
compatible way was deemed to be too much work for too little
gain.
<p>Therefore, developers of profiler modules may rarely need to
update their code to work with new versions of the profiler API.
<p>Developers who wish to support older versions of the API can
perform a compile time check of the
<code>MONO_PROFILER_API_VERSION</code> macro and maintain code
for both old and new versions.
<p>To aid with transitioning to a new version of the profiler
API, the Mono runtime will detect and reject loading profiler
modules which were compiled against older profiler API versions.