|
1 |
| -<h1>Profiling Interface</h1> |
2 |
| - |
3 |
| -<h3>Profiler Operation</h3> |
4 |
| - |
5 |
| - <p>The following methods can be used by dynamic profiler |
6 |
| - methods to monitor different aspects of the program. |
7 |
| - |
8 |
| - <p>A custom profiler will have one public method defined in |
9 |
| - the shared library which is the entry point that Mono calls at |
10 |
| - startup, it has the following signature: |
11 |
| - |
12 |
| - <pre> |
13 |
| - void mono_profiler_startup (const char *desc) |
14 |
| - </pre> |
15 |
| - |
16 |
| - <p>Where "desc" is the set of arguments that were passed from |
17 |
| - the command line. This routine will call |
18 |
| - <tt>mono_profiler_install</tt> to activate the profiler and |
19 |
| - will install one or more filters (one of the various |
20 |
| - <tt>mono_profiler_install_</tt> functions). |
21 |
| - |
22 |
| - <p>In addition, a profiler developer will typically call |
23 |
| - <tt>mono_profiler_set_events</tt> to register which kinds of |
24 |
| - traces should be enabled, these can be an OR-ed combination of |
25 |
| - the following: |
26 |
| - |
27 |
| - <pre> |
28 |
| - MONO_PROFILE_NONE |
29 |
| - MONO_PROFILE_APPDOMAIN_EVENTS |
30 |
| - MONO_PROFILE_ASSEMBLY_EVENTS |
31 |
| - MONO_PROFILE_MODULE_EVENTS |
32 |
| - MONO_PROFILE_CLASS_EVENTS |
33 |
| - MONO_PROFILE_JIT_COMPILATION |
34 |
| - MONO_PROFILE_INLINING |
35 |
| - MONO_PROFILE_EXCEPTIONS |
36 |
| - MONO_PROFILE_ALLOCATIONS |
37 |
| - MONO_PROFILE_GC |
38 |
| - MONO_PROFILE_THREADS |
39 |
| - MONO_PROFILE_REMOTING |
40 |
| - MONO_PROFILE_TRANSITIONS |
41 |
| - MONO_PROFILE_ENTER_LEAVE |
42 |
| - MONO_PROFILE_COVERAGE |
43 |
| - MONO_PROFILE_INS_COVERAGE |
44 |
| - MONO_PROFILE_STATISTICAL |
45 |
| - </pre> |
46 |
| - |
47 |
| - <p>Developers can change the set of monitored events at |
48 |
| - runtime by calling <tt>mono_profiler_set_events</tt>. |
49 |
| - |
50 |
| -<h4><a name="api:mono_profiler_install">mono_profiler_install</a></h4> |
51 |
| -<h4><a name="api:mono_profiler_install_allocation">mono_profiler_install_allocation</a></h4> |
52 |
| -<h4><a name="api:mono_profiler_install_appdomain">mono_profiler_install_appdomain</a></h4> |
53 |
| -<h4><a name="api:mono_profiler_install_assembly">mono_profiler_install_assembly</a></h4> |
54 |
| -<h4><a name="api:mono_profiler_install_class">mono_profiler_install_class</a></h4> |
55 |
| -<h4><a name="api:mono_profiler_install_coverage_filter">mono_profiler_install_coverage_filter</a></h4> |
56 |
| -<h4><a name="api:mono_profiler_install_enter_leave">mono_profiler_install_enter_leave</a></h4> |
57 |
| -<h4><a name="api:mono_profiler_install_jit_compile">mono_profiler_install_jit_compile</a></h4> |
58 |
| -<h4><a name="api:mono_profiler_install_module">mono_profiler_install_module</a></h4> |
59 |
| -<h4><a name="api:mono_profiler_install_thread">mono_profiler_install_thread</a></h4> |
60 |
| -<h4><a name="api:mono_profiler_install_transition">mono_profiler_install_transition</a></h4> |
61 |
| -<h4><a name="api:mono_profiler_install_gc">mono_profiler_install_gc</a></h4> |
62 |
| -<h4><a name="api:mono_profiler_install_statistical">mono_profiler_install_statistical</a></h4> |
63 |
| -<h4><a name="api:mono_profiler_set_events">mono_profiler_set_events</a></h4> |
64 |
| -<h4><a name="api:mono_profiler_get_events">mono_profiler_get_events</a></h4> |
65 |
| - |
66 |
| -<h3>Coverage</h3> |
67 |
| - |
68 |
| - <p>To support profiling modules that need to do code coverage |
69 |
| - analysis, the following routines is provided: |
70 |
| - |
71 |
| -<h4><a name="api:mono_profiler_coverage_get">mono_profiler_coverage_get</a></h4> |
| 1 | +<h1>Runtime Profiler API</h1> |
72 | 2 |
|
| 3 | + <p>The profiler API can be used by dynamically loaded profiler |
| 4 | + modules to monitor different aspects of a running program. The |
| 5 | + API is also usable by embedders without having to compile a |
| 6 | + profiler module. |
73 | 7 |
|
| 8 | +<h2>Profiler Modules</h2> |
| 9 | + |
| 10 | + <p>A profiler module is simply a shared library with a single |
| 11 | + exported function which is the entry point that Mono calls at |
| 12 | + startup. It must have the following signature: |
| 13 | + |
| 14 | + <pre><code class="mapi-codeblock"> |
| 15 | +void mono_profiler_startup_example (const char *desc) |
| 16 | + </code></pre> |
| 17 | + |
| 18 | + <p>Here, the <code>example</code> portion of the function name is |
| 19 | + the name of the profiler module. It must match the shared library |
| 20 | + name (i.e. <code>libmono-profiler-example.so</code>). <i>desc</i> |
| 21 | + is the set of arguments that were passed from the command line. |
| 22 | + |
| 23 | + <p>For example, a bare bones profiler module might look like this |
| 24 | + (<code>example.c</code>): |
| 25 | + |
| 26 | + <pre><code class="mapi-codeblock"> |
| 27 | +#include <mono/metadata/profiler.h> |
| 28 | +#include <stdio.h> |
| 29 | + |
| 30 | +struct _MonoProfiler { |
| 31 | + int dummy; |
| 32 | +} |
| 33 | + |
| 34 | +static MonoProfiler profiler; |
| 35 | + |
| 36 | +static void |
| 37 | +runtime_inited (MonoProfiler *prof) |
| 38 | +{ |
| 39 | + printf ("Hello World"); |
| 40 | +} |
| 41 | + |
| 42 | +void |
| 43 | +mono_profiler_init_example (const char *desc) |
| 44 | +{ |
| 45 | + MonoProfilerHandle handle = mono_profiler_create (&profiler); |
| 46 | + mono_profiler_set_runtime_initialized_callback (handle, runtime_inited); |
| 47 | +} |
| 48 | + </code></pre> |
| 49 | + |
| 50 | + <p>To compile this module, a C compiler must be invoked in a |
| 51 | + similar fashion to this, on Linux: |
| 52 | + |
| 53 | + <pre><code class="mapi-codeblock"> |
| 54 | +gcc -fPIC -shared -o libmono-profiler-example.so example.c `pkg-config --cflags mono-2` |
| 55 | + </code></pre> |
| 56 | + |
| 57 | + <p>Or on OS X: |
| 58 | + |
| 59 | + <pre><code class="mapi-codeblock"> |
| 60 | +gcc -undefined suppress -flat_namespace -o libmono-profiler-example.so example.c `pkg-config --cflags mono-2` |
| 61 | + </code></pre> |
| 62 | + |
| 63 | + <p>You can then load the module using: |
| 64 | + |
| 65 | + <pre><code class="mapi-codeblock"> |
| 66 | +mono --profile=example hello.exe |
| 67 | + </code></pre> |
| 68 | + |
| 69 | + <p>(Note that adjusting <code>LD_LIBRARY_PATH</code> may be |
| 70 | + necessary in order for the dynamic linker to find the module.) |
| 71 | + |
| 72 | +<h2>Profiler Functions</h2> |
| 73 | + |
| 74 | + <p>These are the functions usable for profiling programs. |
| 75 | + |
| 76 | + <p>Each function has a note indicating whether they're async |
| 77 | + safe. An async safe function can be invoked in a signal handler |
| 78 | + or when the world is stopped by the GC. Conversely, a function |
| 79 | + that is not async safe must not be invoked in such a context or |
| 80 | + undefined behavior can occur (crashes, deadlocks, etc). |
| 81 | + |
| 82 | + <p>Some functions may only be invoked from a profiler module's |
| 83 | + init function (or prior to running managed code in the case of |
| 84 | + embedding). This is noted explicitly only if applicable to a |
| 85 | + function. |
| 86 | + |
| 87 | +<h3>Basic Functions</h3> |
| 88 | + |
| 89 | + <p>These functions are used to load and install profilers. |
| 90 | + |
| 91 | +<h4><a name="api:mono_profiler_load">mono_profiler_load</a></h4> |
| 92 | +<h4><a name="api:mono_profiler_create">mono_profiler_create</a></h4> |
| 93 | +<h4><a name="api:mono_profiler_set_cleanup_callback">mono_profiler_set_cleanup_callback</a></h4> |
| 94 | + |
| 95 | +<h3>Code Coverage</h3> |
| 96 | + |
| 97 | + <p>These functions provide access to the JIT compiler's code |
| 98 | + coverage support. This functionality can be used to collect |
| 99 | + information about how many times certain code paths have been |
| 100 | + executed. |
| 101 | + |
| 102 | +<h4><a name="api:mono_profiler_enable_coverage">mono_profiler_enable_coverage</a></h4> |
| 103 | +<h4><a name="api:mono_profiler_set_coverage_filter_callback">mono_profiler_set_coverage_filter_callback</a></h4> |
| 104 | +<h4><a name="api:mono_profiler_get_coverage_data">mono_profiler_get_coverage_data</a></h4> |
| 105 | + |
| 106 | +<h3>Statistical Sampling</h3> |
| 107 | + |
| 108 | + <p>Statistical sampling can be used to interrupt managed threads |
| 109 | + based on a certain mode and frequency for the purpose of |
| 110 | + collecting data about their current work. |
| 111 | + |
| 112 | + <p>One common use case for this functionality, usually referred |
| 113 | + to as call sampling, is to collect a backtrace from every thread |
| 114 | + when a sampling hit event arrives. This data can then be compiled |
| 115 | + into a report indicating where a program spends most of its time. |
| 116 | + |
| 117 | +<h4><a name="api:mono_profiler_enable_sampling">mono_profiler_enable_sampling</a></h4> |
| 118 | +<h4><a name="api:mono_profiler_set_sample_mode">mono_profiler_set_sample_mode</a></h4> |
| 119 | +<h4><a name="api:mono_profiler_get_sample_mode">mono_profiler_get_sample_mode</a></h4> |
| 120 | + |
| 121 | + <p>A callback must be registered to receive sample hit events. |
| 122 | + Please see the <i>Callback Registration</i> section below. |
| 123 | + |
| 124 | +<h3>GC Allocations</h3> |
| 125 | + |
| 126 | + <p>Profilers can be notified about all GC allocations performed |
| 127 | + by a program or the Mono runtime. |
| 128 | + |
| 129 | +<h4><a name="api:mono_profiler_enable_allocations">mono_profiler_enable_allocations</a></h4> |
| 130 | + |
| 131 | + <p>A callback must be registered to receive allocation events. |
| 132 | + Please see the <i>Callback Registration</i> section below. |
| 133 | + |
| 134 | +<h3>Call Instrumentation</h3> |
| 135 | + |
| 136 | + <p>The JIT compiler supports instrumenting managed method entry |
| 137 | + and exit points so that a profiler callback will be invoked. |
| 138 | + |
| 139 | + <p>While such callbacks by themselves have traditionally only |
| 140 | + been useful for call count profiling and the like, Mono gives |
| 141 | + these callbacks access to the arguments, locals, and return |
| 142 | + value of instrumented methods (together referred to as the 'call |
| 143 | + context'). This enables many profiling scenarios that would |
| 144 | + otherwise have required explicit hooks in the base class |
| 145 | + libraries. |
| 146 | + |
| 147 | +<h4><a name="api:mono_profiler_set_call_instrumentation_filter_callback">mono_profiler_set_call_instrumentation_filter_callback</a></h4> |
| 148 | +<h4><a name="api:mono_profiler_enable_call_context_introspection">mono_profiler_enable_call_context_introspection</a></h4> |
| 149 | +<h4><a name="api:mono_profiler_call_context_get_this">mono_profiler_call_context_get_this</a></h4> |
| 150 | +<h4><a name="api:mono_profiler_call_context_get_argument">mono_profiler_call_context_get_argument</a></h4> |
| 151 | +<h4><a name="api:mono_profiler_call_context_get_local">mono_profiler_call_context_get_local</a></h4> |
| 152 | +<h4><a name="api:mono_profiler_call_context_get_result">mono_profiler_call_context_get_result</a></h4> |
| 153 | +<h4><a name="api:mono_profiler_call_context_free_buffer">mono_profiler_call_context_free_buffer</a></h4> |
| 154 | + |
| 155 | + <p>Callbacks must be registered to receive method entry and exit |
| 156 | + events. Please see the <i>Callback Registration</i> section |
| 157 | + below. |
| 158 | + |
| 159 | +<h3>Callback Registration</h3> |
| 160 | + |
| 161 | + <p>In addition to the above functions, there's a large set of |
| 162 | + functions for installing generic profiler event callbacks. These |
| 163 | + are generated from C macros and so are not documented here. |
| 164 | + Please refer to the <code>mono/metadata/profiler.h</code> and |
| 165 | + <code>mono/metadata/profiler-events.h</code> headers for a full |
| 166 | + listing of these. |
| 167 | + |
| 168 | + <p>Callback registration functions are all async safe and can be |
| 169 | + safely invoked from multiple threads at the same time, with the |
| 170 | + caveat that altering a registered callback from one thread will |
| 171 | + not immediately affect another thread that is already invoking |
| 172 | + the current callback. |
| 173 | + |
| 174 | +<h2>API Stability</h2> |
| 175 | + |
| 176 | + <p>The profiler API does not have the same API stability |
| 177 | + garantees that the rest of the Mono embedding API does. While |
| 178 | + a breaking change to the profiler API is extremely rare, it has |
| 179 | + happened in the past when changing the API in a backwards |
| 180 | + compatible way was deemed to be too much work for too little |
| 181 | + gain. |
| 182 | + |
| 183 | + <p>Therefore, developers of profiler modules may rarely need to |
| 184 | + update their code to work with new versions of the profiler API. |
| 185 | + |
| 186 | + <p>Developers who wish to support older versions of the API can |
| 187 | + perform a compile time check of the |
| 188 | + <code>MONO_PROFILER_API_VERSION</code> macro and maintain code |
| 189 | + for both old and new versions. |
| 190 | + |
| 191 | + <p>To aid with transitioning to a new version of the profiler |
| 192 | + API, the Mono runtime will detect and reject loading profiler |
| 193 | + modules which were compiled against older profiler API versions. |
0 commit comments