Lines Matching +full:build +full:- +full:with +full:- +full:python
1 .. highlight:: shell-session
6 Instrumenting CPython with DTrace and SystemTap
14 domain-specific languages allowing a user to write scripts which:
16 - filter which processes are to be observed
17 - gather data from the processes of interest
18 - generate reports on the data
20 As of Python 3.6, CPython can be built with embedded "markers", also
25 .. impl-detail::
34 ---------------------------
36 macOS comes with built-in support for DTrace. On Linux, in order to
37 build CPython with the embedded markers for SystemTap, the SystemTap
42 $ yum install systemtap-sdt-devel
46 $ sudo apt-get install systemtap-sdt-dev
49 CPython must then be :option:`configured with the --with-dtrace option
50 <--with-dtrace>`:
52 .. code-block:: none
54 checking for --with-dtrace... yes
56 On macOS, you can list available DTrace probes by running a Python
58 Python provider::
60 $ python3.6 -q &
61 $ sudo dtrace -l -P python$! # or: dtrace -l -m python3.6
64 29564 python18035 python3.6 _PyEval_EvalFrameDefault function-entry
65 29565 python18035 python3.6 dtrace_function_entry function-entry
66 29566 python18035 python3.6 _PyEval_EvalFrameDefault function-return
67 29567 python18035 python3.6 dtrace_function_return function-return
68 29568 python18035 python3.6 collect gc-done
69 29569 python18035 python3.6 collect gc-start
78 $ readelf -S ./python | grep .note.stapsdt
81 If you've built Python as a shared library
82 (with the :option:`--enable-shared` configure option), you
85 $ readelf -S libpython3.3dm.so.1.0 | grep .note.stapsdt
90 $ readelf -n ./python
92 Displaying notes found at file offset 0x00000254 with length 0x00000020:
97 Displaying notes found at file offset 0x00000274 with length 0x00000024:
99 GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
100 Build ID: df924a2b08a7e89f6e11251d4602022977af2670
102 Displaying notes found at file offset 0x002d6c30 with length 0x00000144:
105 Provider: python
108 Arguments: -4@%ebx
110 Provider: python
113 Arguments: -8@%rax
115 Provider: python
118 Arguments: 8@%rbp 8@%r12 -4@%eax
120 Provider: python
123 Arguments: 8@%rbp 8@%r12 -4@%eax
131 --------------------
134 hierarchy of a Python script, only tracing within the invocation of
135 a function called "start". In other words, import-time function
138 .. code-block:: none
142 python$target:::function-entry
145 self->trace = 1;
148 python$target:::function-entry
149 /self->trace/
152 printf("%*s", self->indent, "");
154 self->indent++;
157 python$target:::function-return
158 /self->trace/
160 self->indent--;
162 printf("%*s", self->indent, "");
166 python$target:::function-return
169 self->trace = 0;
174 $ sudo dtrace -q -s call_stack.d -c "python3.6 script.py"
178 .. code-block:: none
180 156641360502280 function-entry:call_stack.py:start:23
181 156641360518804 function-entry: call_stack.py:function_1:1
182 156641360532797 function-entry: call_stack.py:function_3:9
183 156641360546807 function-return: call_stack.py:function_3:10
184 156641360563367 function-return: call_stack.py:function_1:2
185 156641360578365 function-entry: call_stack.py:function_2:5
186 156641360591757 function-entry: call_stack.py:function_1:1
187 156641360605556 function-entry: call_stack.py:function_3:9
188 156641360617482 function-return: call_stack.py:function_3:10
189 156641360629814 function-return: call_stack.py:function_1:2
190 156641360642285 function-return: call_stack.py:function_2:6
191 156641360656770 function-entry: call_stack.py:function_3:9
192 156641360669707 function-return: call_stack.py:function_3:10
193 156641360687853 function-entry: call_stack.py:function_4:13
194 156641360700719 function-return: call_stack.py:function_4:14
195 156641360719640 function-entry: call_stack.py:function_5:18
196 156641360732567 function-return: call_stack.py:function_5:21
197 156641360747370 function-return:call_stack.py:start:28
201 ------------------------
203 The low-level way to use the SystemTap integration is to use the static
208 hierarchy of a Python script:
210 .. code-block:: none
212 probe process("python").mark("function__entry") {
221 probe process("python").mark("function__return") {
227 thread_indent(-1), funcname, filename, lineno);
233 show-call-hierarchy.stp \
234 -c "./python test.py"
238 .. code-block:: none
240 11408 python(8274): => __contains__ in Lib/_abcoll.py:362
241 11414 python(8274): => __getitem__ in Lib/os.py:425
242 11418 python(8274): => encode in Lib/os.py:490
243 11424 python(8274): <= encode in Lib/os.py:493
244 11428 python(8274): <= __getitem__ in Lib/os.py:426
245 11433 python(8274): <= __contains__ in Lib/_abcoll.py:366
249 - time in microseconds since start of script
251 - name of executable
253 - PID of process
257 For a :option:`--enable-shared` build of CPython, the markers are contained within the
261 .. code-block:: none
263 probe process("python").mark("function__entry") {
267 .. code-block:: none
269 probe process("python").library("libpython3.6dm.so.1.0").mark("function__entry") {
271 (assuming a :ref:`debug build <debug-build>` of CPython 3.6)
275 ------------------------
279 This marker indicates that execution of a Python function has begun.
280 It is only triggered for pure-Python (bytecode) functions.
296 execution of a Python function has ended (either via ``return``, or via an
297 exception). It is only triggered for pure-Python (bytecode) functions.
303 This marker indicates a Python line is about to be executed. It is
304 the equivalent of line-by-line tracing with a Python profiler. It is
311 Fires when the Python interpreter starts a garbage collection cycle.
316 Fires when the Python interpreter finishes a garbage collection
345 -----------------
347 The higher-level way to use the SystemTap integration is to use a "tapset":
348 SystemTap's equivalent of a library, which hides some of the lower-level
351 Here is a tapset file, based on a non-shared build of CPython:
353 .. code-block:: none
356 Provide a higher-level wrapping around the function__entry and
359 probe python.function.entry = process("python").mark("function__entry")
366 probe python.function.return = process("python").mark("function__return")
378 .. object:: python.function.entry(str filename, str funcname, int lineno, frameptr)
380 This probe point indicates that execution of a Python function has begun.
381 It is only triggered for pure-Python (bytecode) functions.
383 .. object:: python.function.return(str filename, str funcname, int lineno, frameptr)
385 This probe point is the converse of ``python.function.return``, and
386 indicates that execution of a Python function has ended (either via
387 ``return``, or via an exception). It is only triggered for pure-Python
392 --------
394 example given above of tracing the Python function-call hierarchy, without
397 .. code-block:: none
399 probe python.function.entry
405 probe python.function.return
408 thread_indent(-1), funcname, filename, lineno);
412 The following script uses the tapset above to provide a top-like view of all
416 .. code-block:: none
420 probe python.function.entry
429 foreach ([pid, filename, funcname, lineno] in fn_calls- limit 20) {