Skip to content

Commit 20de418

Browse files
authored
Merge pull request mono#6078 from alexrp/profiler-docs
[profiler] Some documentation improvements * Update and rewrite profiler-related `man` pages. * Update profiler API documentation for the new API. * Extend the `exdoc` tool to support some more Doxygen features. * Document the AOT profiler's file format. * Clean up the sample profiler module and add a makefile. * Include context/domain reports in `mprof-report`'s default report set. * Exit the process when the `help` option is passed to the profilers. * Remove the IOMap profiler. * Remove some deprecated options from the log profiler's `help` output. * Clean up the AOT profiler and bring its user interface in line with the others. * Allow comments in coverage filter files.
2 parents 41a3571 + f3706fa commit 20de418

25 files changed

+1559
-1739
lines changed

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
/llvm @vargaz
3636

3737
/man @marek-safar @miguel
38-
/man/mprof-report.1 @alexrp
38+
/man/*prof* @alexrp
3939

4040
/mcs @marek-safar
4141

docs/api-style.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,16 @@
4343
line-height: 0px;
4444
}
4545

46+
.mapi-codeblock {
47+
display: block;
48+
padding: 5pt 5pt;
49+
margin: 10pt;
50+
white-space: pre;
51+
font-family: monospace;
52+
border: 1px solid rgba(233,233,233,1);
53+
background-color: rgba(249,249,249,1);
54+
}
55+
4656
.mapi-entry code {
4757
border: none;
4858
background-color: transparent;

docs/exdoc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ sub process_function {
124124
my $body = '';
125125
my $returns = '';
126126
my $prototype = '';
127+
my $codeblock = 'false';
127128

128129
while (<$file>) {
129130

@@ -156,7 +157,6 @@ sub process_function {
156157
if (defined($deprecated)) {
157158
process_formatting(\$deprecated, $file_path, $.);
158159
}
159-
$body =~ s/\n/ /g;
160160

161161
if (exists($docs->{body}->{$name})) {
162162
my $origin = $docs->{origin}->{$name};
@@ -180,8 +180,16 @@ sub process_function {
180180
chomp;
181181
s/^ +\*//;
182182

183-
# Replace blank lines with paragraph breaks.
184-
$_ = '<p>' if /^\s*$/;
183+
if (/\s*\\code$/) {
184+
$codeblock = 'true';
185+
} elsif (/\s*\\endcode$/) {
186+
$codeblock = 'false';
187+
}
188+
189+
# Replace blank lines with paragraph breaks if we're not in a code block.
190+
if (/^\s*$/) {
191+
$_ = '<p>' if $codeblock eq 'false';
192+
}
185193

186194
if ($section == $PARAMETER_SECTION) {
187195
if (/\s*\\param +(\w+)(.*)/) {
@@ -210,7 +218,7 @@ sub process_function {
210218
$returns = "\t$_\n";
211219
$section = $RETURN_SECTION;
212220
} else {
213-
$body .= "\n\t$_";
221+
$body .= "\n$_";
214222
}
215223
} elsif ($section == $RETURN_SECTION) {
216224
$returns .= "\n\t$_";
@@ -227,6 +235,12 @@ sub process_formatting {
227235
my ($content, $file_path, $current_line) = @_;
228236
$_ = $$content;
229237

238+
# General formatting
239+
s{\\b +(\w+)}{<strong>$1</strong>}g;
240+
s{\\a +(\w+)}{<i>$1</i>}g;
241+
s{\\e +(\w+)}{<i>$1</i>}g;
242+
s{\\em +(\w+)}{<i>$1</i>}g;
243+
230244
# Constants
231245
s{NULL}{<code>NULL</code>}g;
232246
s{TRUE}{<code>TRUE</code>}g;
@@ -243,6 +257,8 @@ sub process_formatting {
243257
warn "$file_path:$current_line: Old-style monodoc notation '`code`' used\n"
244258
if s{\`((?!api:)[:.\w\*]+)\`}{<code>$1</code>}g && $WARNINGS;
245259
s{\\c +(\S+(?<![.,:;]))}{<code>$1</code>}g;
260+
s{\\code}{<pre><code class="mapi-codeblock">}g;
261+
s{\\endcode}{</code></pre>}g;
246262

247263
$$content = $_;
248264
}

docs/sources/mono-api-profiler.html

Lines changed: 191 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,193 @@
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>
722

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.
737

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 &lt;mono/metadata/profiler.h&gt;
28+
#include &lt;stdio.h&gt;
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 (&amp;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.

man/Makefile.am

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ man_MANS = \
5858
mono-configuration-crypto.1 \
5959
ccrewrite.1 \
6060
cccheck.1 \
61-
mono-symbolicate.1
61+
mono-symbolicate.1 \
62+
mono-profilers.1
6263

6364
EXTRA_DIST = $(man_MANS)

0 commit comments

Comments
 (0)