instrumentation.html 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
  6. <meta property="og:title" content="Instrumenting CPython with DTrace and SystemTap" />
  7. <meta property="og:type" content="website" />
  8. <meta property="og:url" content="https://docs.python.org/3/howto/instrumentation.html" />
  9. <meta property="og:site_name" content="Python documentation" />
  10. <meta property="og:description" content="author, David Malcolm,, author, Łukasz Langa,. DTrace and SystemTap are monitoring tools, each providing a way to inspect what the processes on a computer system are doing. They both use domain-spe..." />
  11. <meta property="og:image" content="https://docs.python.org/3/_static/og-image.png" />
  12. <meta property="og:image:alt" content="Python documentation" />
  13. <meta name="description" content="author, David Malcolm,, author, Łukasz Langa,. DTrace and SystemTap are monitoring tools, each providing a way to inspect what the processes on a computer system are doing. They both use domain-spe..." />
  14. <meta property="og:image:width" content="200" />
  15. <meta property="og:image:height" content="200" />
  16. <meta name="theme-color" content="#3776ab" />
  17. <title>Instrumenting CPython with DTrace and SystemTap &#8212; Python 3.12.0 documentation</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
  18. <link rel="stylesheet" type="text/css" href="../_static/pygments.css" />
  19. <link rel="stylesheet" type="text/css" href="../_static/pydoctheme.css?digest=b37c26da2f7529d09fe70b41c4b2133fe4931a90" />
  20. <link id="pygments_dark_css" media="(prefers-color-scheme: dark)" rel="stylesheet" type="text/css" href="../_static/pygments_dark.css" />
  21. <script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js"></script>
  22. <script src="../_static/jquery.js"></script>
  23. <script src="../_static/underscore.js"></script>
  24. <script src="../_static/doctools.js"></script>
  25. <script src="../_static/sidebar.js"></script>
  26. <link rel="search" type="application/opensearchdescription+xml"
  27. title="Search within Python 3.12.0 documentation"
  28. href="../_static/opensearch.xml"/>
  29. <link rel="author" title="About these documents" href="../about.html" />
  30. <link rel="index" title="Index" href="../genindex.html" />
  31. <link rel="search" title="Search" href="../search.html" />
  32. <link rel="copyright" title="Copyright" href="../copyright.html" />
  33. <link rel="next" title="Python support for the Linux perf profiler" href="perf_profiling.html" />
  34. <link rel="prev" title="Argument Clinic How-To" href="clinic.html" />
  35. <link rel="canonical" href="https://docs.python.org/3/howto/instrumentation.html" />
  36. <style>
  37. @media only screen {
  38. table.full-width-table {
  39. width: 100%;
  40. }
  41. }
  42. </style>
  43. <link rel="stylesheet" href="../_static/pydoctheme_dark.css" media="(prefers-color-scheme: dark)" id="pydoctheme_dark_css">
  44. <link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
  45. <script type="text/javascript" src="../_static/copybutton.js"></script>
  46. <script type="text/javascript" src="../_static/menu.js"></script>
  47. <script type="text/javascript" src="../_static/themetoggle.js"></script>
  48. </head>
  49. <body>
  50. <div class="mobile-nav">
  51. <input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
  52. aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
  53. <nav class="nav-content" role="navigation">
  54. <label for="menuToggler" class="toggler__label">
  55. <span></span>
  56. </label>
  57. <span class="nav-items-wrapper">
  58. <a href="https://www.python.org/" class="nav-logo">
  59. <img src="../_static/py.svg" alt="Logo"/>
  60. </a>
  61. <span class="version_switcher_placeholder"></span>
  62. <form role="search" class="search" action="../search.html" method="get">
  63. <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
  64. <path fill-rule="nonzero" fill="currentColor" d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"></path>
  65. </svg>
  66. <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
  67. <input type="submit" value="Go"/>
  68. </form>
  69. </span>
  70. </nav>
  71. <div class="menu-wrapper">
  72. <nav class="menu" role="navigation" aria-label="main navigation">
  73. <div class="language_switcher_placeholder"></div>
  74. <label class="theme-selector-label">
  75. Theme
  76. <select class="theme-selector" oninput="activateTheme(this.value)">
  77. <option value="auto" selected>Auto</option>
  78. <option value="light">Light</option>
  79. <option value="dark">Dark</option>
  80. </select>
  81. </label>
  82. <div>
  83. <h3><a href="../contents.html">Table of Contents</a></h3>
  84. <ul>
  85. <li><a class="reference internal" href="#">Instrumenting CPython with DTrace and SystemTap</a><ul>
  86. <li><a class="reference internal" href="#enabling-the-static-markers">Enabling the static markers</a></li>
  87. <li><a class="reference internal" href="#static-dtrace-probes">Static DTrace probes</a></li>
  88. <li><a class="reference internal" href="#static-systemtap-markers">Static SystemTap markers</a></li>
  89. <li><a class="reference internal" href="#available-static-markers">Available static markers</a></li>
  90. <li><a class="reference internal" href="#systemtap-tapsets">SystemTap Tapsets</a></li>
  91. <li><a class="reference internal" href="#examples">Examples</a></li>
  92. </ul>
  93. </li>
  94. </ul>
  95. </div>
  96. <div>
  97. <h4>Previous topic</h4>
  98. <p class="topless"><a href="clinic.html"
  99. title="previous chapter">Argument Clinic How-To</a></p>
  100. </div>
  101. <div>
  102. <h4>Next topic</h4>
  103. <p class="topless"><a href="perf_profiling.html"
  104. title="next chapter">Python support for the Linux <code class="docutils literal notranslate"><span class="pre">perf</span></code> profiler</a></p>
  105. </div>
  106. <div role="note" aria-label="source link">
  107. <h3>This Page</h3>
  108. <ul class="this-page-menu">
  109. <li><a href="../bugs.html">Report a Bug</a></li>
  110. <li>
  111. <a href="https://github.com/python/cpython/blob/main/Doc/howto/instrumentation.rst"
  112. rel="nofollow">Show Source
  113. </a>
  114. </li>
  115. </ul>
  116. </div>
  117. </nav>
  118. </div>
  119. </div>
  120. <div class="related" role="navigation" aria-label="related navigation">
  121. <h3>Navigation</h3>
  122. <ul>
  123. <li class="right" style="margin-right: 10px">
  124. <a href="../genindex.html" title="General Index"
  125. accesskey="I">index</a></li>
  126. <li class="right" >
  127. <a href="../py-modindex.html" title="Python Module Index"
  128. >modules</a> |</li>
  129. <li class="right" >
  130. <a href="perf_profiling.html" title="Python support for the Linux perf profiler"
  131. accesskey="N">next</a> |</li>
  132. <li class="right" >
  133. <a href="clinic.html" title="Argument Clinic How-To"
  134. accesskey="P">previous</a> |</li>
  135. <li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
  136. <li><a href="https://www.python.org/">Python</a> &#187;</li>
  137. <li class="switchers">
  138. <div class="language_switcher_placeholder"></div>
  139. <div class="version_switcher_placeholder"></div>
  140. </li>
  141. <li>
  142. </li>
  143. <li id="cpython-language-and-version">
  144. <a href="../index.html">3.12.0 Documentation</a> &#187;
  145. </li>
  146. <li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python HOWTOs</a> &#187;</li>
  147. <li class="nav-item nav-item-this"><a href="">Instrumenting CPython with DTrace and SystemTap</a></li>
  148. <li class="right">
  149. <div class="inline-search" role="search">
  150. <form class="inline-search" action="../search.html" method="get">
  151. <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
  152. <input type="submit" value="Go" />
  153. </form>
  154. </div>
  155. |
  156. </li>
  157. <li class="right">
  158. <label class="theme-selector-label">
  159. Theme
  160. <select class="theme-selector" oninput="activateTheme(this.value)">
  161. <option value="auto" selected>Auto</option>
  162. <option value="light">Light</option>
  163. <option value="dark">Dark</option>
  164. </select>
  165. </label> |</li>
  166. </ul>
  167. </div>
  168. <div class="document">
  169. <div class="documentwrapper">
  170. <div class="bodywrapper">
  171. <div class="body" role="main">
  172. <section id="instrumenting-cpython-with-dtrace-and-systemtap">
  173. <span id="instrumentation"></span><h1>Instrumenting CPython with DTrace and SystemTap<a class="headerlink" href="#instrumenting-cpython-with-dtrace-and-systemtap" title="Permalink to this headline">¶</a></h1>
  174. <dl class="field-list simple">
  175. <dt class="field-odd">author</dt>
  176. <dd class="field-odd"><p>David Malcolm</p>
  177. </dd>
  178. <dt class="field-even">author</dt>
  179. <dd class="field-even"><p>Łukasz Langa</p>
  180. </dd>
  181. </dl>
  182. <p>DTrace and SystemTap are monitoring tools, each providing a way to inspect
  183. what the processes on a computer system are doing. They both use
  184. domain-specific languages allowing a user to write scripts which:</p>
  185. <blockquote>
  186. <div><ul class="simple">
  187. <li><p>filter which processes are to be observed</p></li>
  188. <li><p>gather data from the processes of interest</p></li>
  189. <li><p>generate reports on the data</p></li>
  190. </ul>
  191. </div></blockquote>
  192. <p>As of Python 3.6, CPython can be built with embedded “markers”, also
  193. known as “probes”, that can be observed by a DTrace or SystemTap script,
  194. making it easier to monitor what the CPython processes on a system are
  195. doing.</p>
  196. <div class="impl-detail compound">
  197. <p><strong>CPython implementation detail:</strong> DTrace markers are implementation details of the CPython interpreter.
  198. No guarantees are made about probe compatibility between versions of
  199. CPython. DTrace scripts can stop working or work incorrectly without
  200. warning when changing CPython versions.</p>
  201. </div>
  202. <section id="enabling-the-static-markers">
  203. <h2>Enabling the static markers<a class="headerlink" href="#enabling-the-static-markers" title="Permalink to this headline">¶</a></h2>
  204. <p>macOS comes with built-in support for DTrace. On Linux, in order to
  205. build CPython with the embedded markers for SystemTap, the SystemTap
  206. development tools must be installed.</p>
  207. <p>On a Linux machine, this can be done via:</p>
  208. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>yum<span class="w"> </span>install<span class="w"> </span>systemtap-sdt-devel
  209. </pre></div>
  210. </div>
  211. <p>or:</p>
  212. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>systemtap-sdt-dev
  213. </pre></div>
  214. </div>
  215. <p>CPython must then be <a class="reference internal" href="../using/configure.html#cmdoption-with-dtrace"><code class="xref std std-option docutils literal notranslate"><span class="pre">configured</span> <span class="pre">with</span> <span class="pre">the</span> <span class="pre">--with-dtrace</span> <span class="pre">option</span></code></a>:</p>
  216. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>checking for --with-dtrace... yes
  217. </pre></div>
  218. </div>
  219. <p>On macOS, you can list available DTrace probes by running a Python
  220. process in the background and listing all probes made available by the
  221. Python provider:</p>
  222. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>python3.6<span class="w"> </span>-q<span class="w"> </span><span class="p">&amp;</span>
  223. <span class="gp">$ </span>sudo<span class="w"> </span>dtrace<span class="w"> </span>-l<span class="w"> </span>-P<span class="w"> </span>python<span class="nv">$!</span><span class="w"> </span><span class="c1"># or: dtrace -l -m python3.6</span>
  224. <span class="go"> ID PROVIDER MODULE FUNCTION NAME</span>
  225. <span class="go">29564 python18035 python3.6 _PyEval_EvalFrameDefault function-entry</span>
  226. <span class="go">29565 python18035 python3.6 dtrace_function_entry function-entry</span>
  227. <span class="go">29566 python18035 python3.6 _PyEval_EvalFrameDefault function-return</span>
  228. <span class="go">29567 python18035 python3.6 dtrace_function_return function-return</span>
  229. <span class="go">29568 python18035 python3.6 collect gc-done</span>
  230. <span class="go">29569 python18035 python3.6 collect gc-start</span>
  231. <span class="go">29570 python18035 python3.6 _PyEval_EvalFrameDefault line</span>
  232. <span class="go">29571 python18035 python3.6 maybe_dtrace_line line</span>
  233. </pre></div>
  234. </div>
  235. <p>On Linux, you can verify if the SystemTap static markers are present in
  236. the built binary by seeing if it contains a “.note.stapsdt” section.</p>
  237. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>readelf<span class="w"> </span>-S<span class="w"> </span>./python<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>.note.stapsdt
  238. <span class="go">[30] .note.stapsdt NOTE 0000000000000000 00308d78</span>
  239. </pre></div>
  240. </div>
  241. <p>If you’ve built Python as a shared library
  242. (with the <a class="reference internal" href="../using/configure.html#cmdoption-enable-shared"><code class="xref std std-option docutils literal notranslate"><span class="pre">--enable-shared</span></code></a> configure option), you
  243. need to look instead within the shared library. For example:</p>
  244. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>readelf<span class="w"> </span>-S<span class="w"> </span>libpython3.3dm.so.1.0<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>.note.stapsdt
  245. <span class="go">[29] .note.stapsdt NOTE 0000000000000000 00365b68</span>
  246. </pre></div>
  247. </div>
  248. <p>Sufficiently modern readelf can print the metadata:</p>
  249. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>readelf<span class="w"> </span>-n<span class="w"> </span>./python
  250. <span class="go">Displaying notes found at file offset 0x00000254 with length 0x00000020:</span>
  251. <span class="go"> Owner Data size Description</span>
  252. <span class="go"> GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)</span>
  253. <span class="go"> OS: Linux, ABI: 2.6.32</span>
  254. <span class="go">Displaying notes found at file offset 0x00000274 with length 0x00000024:</span>
  255. <span class="go"> Owner Data size Description</span>
  256. <span class="go"> GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)</span>
  257. <span class="go"> Build ID: df924a2b08a7e89f6e11251d4602022977af2670</span>
  258. <span class="go">Displaying notes found at file offset 0x002d6c30 with length 0x00000144:</span>
  259. <span class="go"> Owner Data size Description</span>
  260. <span class="go"> stapsdt 0x00000031 NT_STAPSDT (SystemTap probe descriptors)</span>
  261. <span class="go"> Provider: python</span>
  262. <span class="go"> Name: gc__start</span>
  263. <span class="go"> Location: 0x00000000004371c3, Base: 0x0000000000630ce2, Semaphore: 0x00000000008d6bf6</span>
  264. <span class="go"> Arguments: -4@%ebx</span>
  265. <span class="go"> stapsdt 0x00000030 NT_STAPSDT (SystemTap probe descriptors)</span>
  266. <span class="go"> Provider: python</span>
  267. <span class="go"> Name: gc__done</span>
  268. <span class="go"> Location: 0x00000000004374e1, Base: 0x0000000000630ce2, Semaphore: 0x00000000008d6bf8</span>
  269. <span class="go"> Arguments: -8@%rax</span>
  270. <span class="go"> stapsdt 0x00000045 NT_STAPSDT (SystemTap probe descriptors)</span>
  271. <span class="go"> Provider: python</span>
  272. <span class="go"> Name: function__entry</span>
  273. <span class="go"> Location: 0x000000000053db6c, Base: 0x0000000000630ce2, Semaphore: 0x00000000008d6be8</span>
  274. <span class="go"> Arguments: 8@%rbp 8@%r12 -4@%eax</span>
  275. <span class="go"> stapsdt 0x00000046 NT_STAPSDT (SystemTap probe descriptors)</span>
  276. <span class="go"> Provider: python</span>
  277. <span class="go"> Name: function__return</span>
  278. <span class="go"> Location: 0x000000000053dba8, Base: 0x0000000000630ce2, Semaphore: 0x00000000008d6bea</span>
  279. <span class="go"> Arguments: 8@%rbp 8@%r12 -4@%eax</span>
  280. </pre></div>
  281. </div>
  282. <p>The above metadata contains information for SystemTap describing how it
  283. can patch strategically placed machine code instructions to enable the
  284. tracing hooks used by a SystemTap script.</p>
  285. </section>
  286. <section id="static-dtrace-probes">
  287. <h2>Static DTrace probes<a class="headerlink" href="#static-dtrace-probes" title="Permalink to this headline">¶</a></h2>
  288. <p>The following example DTrace script can be used to show the call/return
  289. hierarchy of a Python script, only tracing within the invocation of
  290. a function called “start”. In other words, import-time function
  291. invocations are not going to be listed:</p>
  292. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>self int indent;
  293. python$target:::function-entry
  294. /copyinstr(arg1) == &quot;start&quot;/
  295. {
  296. self-&gt;trace = 1;
  297. }
  298. python$target:::function-entry
  299. /self-&gt;trace/
  300. {
  301. printf(&quot;%d\t%*s:&quot;, timestamp, 15, probename);
  302. printf(&quot;%*s&quot;, self-&gt;indent, &quot;&quot;);
  303. printf(&quot;%s:%s:%d\n&quot;, basename(copyinstr(arg0)), copyinstr(arg1), arg2);
  304. self-&gt;indent++;
  305. }
  306. python$target:::function-return
  307. /self-&gt;trace/
  308. {
  309. self-&gt;indent--;
  310. printf(&quot;%d\t%*s:&quot;, timestamp, 15, probename);
  311. printf(&quot;%*s&quot;, self-&gt;indent, &quot;&quot;);
  312. printf(&quot;%s:%s:%d\n&quot;, basename(copyinstr(arg0)), copyinstr(arg1), arg2);
  313. }
  314. python$target:::function-return
  315. /copyinstr(arg1) == &quot;start&quot;/
  316. {
  317. self-&gt;trace = 0;
  318. }
  319. </pre></div>
  320. </div>
  321. <p>It can be invoked like this:</p>
  322. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>sudo<span class="w"> </span>dtrace<span class="w"> </span>-q<span class="w"> </span>-s<span class="w"> </span>call_stack.d<span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;python3.6 script.py&quot;</span>
  323. </pre></div>
  324. </div>
  325. <p>The output looks like this:</p>
  326. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>156641360502280 function-entry:call_stack.py:start:23
  327. 156641360518804 function-entry: call_stack.py:function_1:1
  328. 156641360532797 function-entry: call_stack.py:function_3:9
  329. 156641360546807 function-return: call_stack.py:function_3:10
  330. 156641360563367 function-return: call_stack.py:function_1:2
  331. 156641360578365 function-entry: call_stack.py:function_2:5
  332. 156641360591757 function-entry: call_stack.py:function_1:1
  333. 156641360605556 function-entry: call_stack.py:function_3:9
  334. 156641360617482 function-return: call_stack.py:function_3:10
  335. 156641360629814 function-return: call_stack.py:function_1:2
  336. 156641360642285 function-return: call_stack.py:function_2:6
  337. 156641360656770 function-entry: call_stack.py:function_3:9
  338. 156641360669707 function-return: call_stack.py:function_3:10
  339. 156641360687853 function-entry: call_stack.py:function_4:13
  340. 156641360700719 function-return: call_stack.py:function_4:14
  341. 156641360719640 function-entry: call_stack.py:function_5:18
  342. 156641360732567 function-return: call_stack.py:function_5:21
  343. 156641360747370 function-return:call_stack.py:start:28
  344. </pre></div>
  345. </div>
  346. </section>
  347. <section id="static-systemtap-markers">
  348. <h2>Static SystemTap markers<a class="headerlink" href="#static-systemtap-markers" title="Permalink to this headline">¶</a></h2>
  349. <p>The low-level way to use the SystemTap integration is to use the static
  350. markers directly. This requires you to explicitly state the binary file
  351. containing them.</p>
  352. <p>For example, this SystemTap script can be used to show the call/return
  353. hierarchy of a Python script:</p>
  354. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>probe process(&quot;python&quot;).mark(&quot;function__entry&quot;) {
  355. filename = user_string($arg1);
  356. funcname = user_string($arg2);
  357. lineno = $arg3;
  358. printf(&quot;%s =&gt; %s in %s:%d\\n&quot;,
  359. thread_indent(1), funcname, filename, lineno);
  360. }
  361. probe process(&quot;python&quot;).mark(&quot;function__return&quot;) {
  362. filename = user_string($arg1);
  363. funcname = user_string($arg2);
  364. lineno = $arg3;
  365. printf(&quot;%s &lt;= %s in %s:%d\\n&quot;,
  366. thread_indent(-1), funcname, filename, lineno);
  367. }
  368. </pre></div>
  369. </div>
  370. <p>It can be invoked like this:</p>
  371. <div class="highlight-shell-session notranslate"><div class="highlight"><pre><span></span><span class="gp">$ </span>stap<span class="w"> </span><span class="se">\</span>
  372. <span class="w"> </span>show-call-hierarchy.stp<span class="w"> </span><span class="se">\</span>
  373. <span class="w"> </span>-c<span class="w"> </span><span class="s2">&quot;./python test.py&quot;</span>
  374. </pre></div>
  375. </div>
  376. <p>The output looks like this:</p>
  377. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>11408 python(8274): =&gt; __contains__ in Lib/_abcoll.py:362
  378. 11414 python(8274): =&gt; __getitem__ in Lib/os.py:425
  379. 11418 python(8274): =&gt; encode in Lib/os.py:490
  380. 11424 python(8274): &lt;= encode in Lib/os.py:493
  381. 11428 python(8274): &lt;= __getitem__ in Lib/os.py:426
  382. 11433 python(8274): &lt;= __contains__ in Lib/_abcoll.py:366
  383. </pre></div>
  384. </div>
  385. <p>where the columns are:</p>
  386. <blockquote>
  387. <div><ul class="simple">
  388. <li><p>time in microseconds since start of script</p></li>
  389. <li><p>name of executable</p></li>
  390. <li><p>PID of process</p></li>
  391. </ul>
  392. </div></blockquote>
  393. <p>and the remainder indicates the call/return hierarchy as the script executes.</p>
  394. <p>For a <a class="reference internal" href="../using/configure.html#cmdoption-enable-shared"><code class="xref std std-option docutils literal notranslate"><span class="pre">--enable-shared</span></code></a> build of CPython, the markers are contained within the
  395. libpython shared library, and the probe’s dotted path needs to reflect this. For
  396. example, this line from the above example:</p>
  397. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>probe process(&quot;python&quot;).mark(&quot;function__entry&quot;) {
  398. </pre></div>
  399. </div>
  400. <p>should instead read:</p>
  401. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>probe process(&quot;python&quot;).library(&quot;libpython3.6dm.so.1.0&quot;).mark(&quot;function__entry&quot;) {
  402. </pre></div>
  403. </div>
  404. <p>(assuming a <a class="reference internal" href="../using/configure.html#debug-build"><span class="std std-ref">debug build</span></a> of CPython 3.6)</p>
  405. </section>
  406. <section id="available-static-markers">
  407. <h2>Available static markers<a class="headerlink" href="#available-static-markers" title="Permalink to this headline">¶</a></h2>
  408. <dl class="object">
  409. <dt class="sig sig-object">
  410. <span class="sig-name descname"><span class="pre">function__entry(str</span> <span class="pre">filename,</span> <span class="pre">str</span> <span class="pre">funcname,</span> <span class="pre">int</span> <span class="pre">lineno)</span></span></dt>
  411. <dd><p>This marker indicates that execution of a Python function has begun.
  412. It is only triggered for pure-Python (bytecode) functions.</p>
  413. <p>The filename, function name, and line number are provided back to the
  414. tracing script as positional arguments, which must be accessed using
  415. <code class="docutils literal notranslate"><span class="pre">$arg1</span></code>, <code class="docutils literal notranslate"><span class="pre">$arg2</span></code>, <code class="docutils literal notranslate"><span class="pre">$arg3</span></code>:</p>
  416. <blockquote>
  417. <div><ul class="simple">
  418. <li><p><code class="docutils literal notranslate"><span class="pre">$arg1</span></code> : <code class="docutils literal notranslate"><span class="pre">(const</span> <span class="pre">char</span> <span class="pre">*)</span></code> filename, accessible using <code class="docutils literal notranslate"><span class="pre">user_string($arg1)</span></code></p></li>
  419. <li><p><code class="docutils literal notranslate"><span class="pre">$arg2</span></code> : <code class="docutils literal notranslate"><span class="pre">(const</span> <span class="pre">char</span> <span class="pre">*)</span></code> function name, accessible using
  420. <code class="docutils literal notranslate"><span class="pre">user_string($arg2)</span></code></p></li>
  421. <li><p><code class="docutils literal notranslate"><span class="pre">$arg3</span></code> : <code class="docutils literal notranslate"><span class="pre">int</span></code> line number</p></li>
  422. </ul>
  423. </div></blockquote>
  424. </dd></dl>
  425. <dl class="object">
  426. <dt class="sig sig-object">
  427. <span class="sig-name descname"><span class="pre">function__return(str</span> <span class="pre">filename,</span> <span class="pre">str</span> <span class="pre">funcname,</span> <span class="pre">int</span> <span class="pre">lineno)</span></span></dt>
  428. <dd><p>This marker is the converse of <code class="xref c c-func docutils literal notranslate"><span class="pre">function__entry()</span></code>, and indicates that
  429. execution of a Python function has ended (either via <code class="docutils literal notranslate"><span class="pre">return</span></code>, or via an
  430. exception). It is only triggered for pure-Python (bytecode) functions.</p>
  431. <p>The arguments are the same as for <code class="xref c c-func docutils literal notranslate"><span class="pre">function__entry()</span></code></p>
  432. </dd></dl>
  433. <dl class="object">
  434. <dt class="sig sig-object">
  435. <span class="sig-name descname"><span class="pre">line(str</span> <span class="pre">filename,</span> <span class="pre">str</span> <span class="pre">funcname,</span> <span class="pre">int</span> <span class="pre">lineno)</span></span></dt>
  436. <dd><p>This marker indicates a Python line is about to be executed. It is
  437. the equivalent of line-by-line tracing with a Python profiler. It is
  438. not triggered within C functions.</p>
  439. <p>The arguments are the same as for <code class="xref c c-func docutils literal notranslate"><span class="pre">function__entry()</span></code>.</p>
  440. </dd></dl>
  441. <dl class="object">
  442. <dt class="sig sig-object">
  443. <span class="sig-name descname"><span class="pre">gc__start(int</span> <span class="pre">generation)</span></span></dt>
  444. <dd><p>Fires when the Python interpreter starts a garbage collection cycle.
  445. <code class="docutils literal notranslate"><span class="pre">arg0</span></code> is the generation to scan, like <a class="reference internal" href="../library/gc.html#gc.collect" title="gc.collect"><code class="xref py py-func docutils literal notranslate"><span class="pre">gc.collect()</span></code></a>.</p>
  446. </dd></dl>
  447. <dl class="object">
  448. <dt class="sig sig-object">
  449. <span class="sig-name descname"><span class="pre">gc__done(long</span> <span class="pre">collected)</span></span></dt>
  450. <dd><p>Fires when the Python interpreter finishes a garbage collection
  451. cycle. <code class="docutils literal notranslate"><span class="pre">arg0</span></code> is the number of collected objects.</p>
  452. </dd></dl>
  453. <dl class="object">
  454. <dt class="sig sig-object">
  455. <span class="sig-name descname"><span class="pre">import__find__load__start(str</span> <span class="pre">modulename)</span></span></dt>
  456. <dd><p>Fires before <a class="reference internal" href="../library/importlib.html#module-importlib" title="importlib: The implementation of the import machinery."><code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a> attempts to find and load the module.
  457. <code class="docutils literal notranslate"><span class="pre">arg0</span></code> is the module name.</p>
  458. <div class="versionadded">
  459. <p><span class="versionmodified added">New in version 3.7.</span></p>
  460. </div>
  461. </dd></dl>
  462. <dl class="object">
  463. <dt class="sig sig-object">
  464. <span class="sig-name descname"><span class="pre">import__find__load__done(str</span> <span class="pre">modulename,</span> <span class="pre">int</span> <span class="pre">found)</span></span></dt>
  465. <dd><p>Fires after <a class="reference internal" href="../library/importlib.html#module-importlib" title="importlib: The implementation of the import machinery."><code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a>’s find_and_load function is called.
  466. <code class="docutils literal notranslate"><span class="pre">arg0</span></code> is the module name, <code class="docutils literal notranslate"><span class="pre">arg1</span></code> indicates if module was
  467. successfully loaded.</p>
  468. <div class="versionadded">
  469. <p><span class="versionmodified added">New in version 3.7.</span></p>
  470. </div>
  471. </dd></dl>
  472. <dl class="object">
  473. <dt class="sig sig-object">
  474. <span class="sig-name descname"><span class="pre">audit(str</span> <span class="pre">event,</span> <span class="pre">void</span> <span class="pre">*tuple)</span></span></dt>
  475. <dd><p>Fires when <a class="reference internal" href="../library/sys.html#sys.audit" title="sys.audit"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.audit()</span></code></a> or <a class="reference internal" href="../c-api/sys.html#c.PySys_Audit" title="PySys_Audit"><code class="xref c c-func docutils literal notranslate"><span class="pre">PySys_Audit()</span></code></a> is called.
  476. <code class="docutils literal notranslate"><span class="pre">arg0</span></code> is the event name as C string, <code class="docutils literal notranslate"><span class="pre">arg1</span></code> is a <a class="reference internal" href="../c-api/structures.html#c.PyObject" title="PyObject"><code class="xref c c-type docutils literal notranslate"><span class="pre">PyObject</span></code></a>
  477. pointer to a tuple object.</p>
  478. <div class="versionadded">
  479. <p><span class="versionmodified added">New in version 3.8.</span></p>
  480. </div>
  481. </dd></dl>
  482. </section>
  483. <section id="systemtap-tapsets">
  484. <h2>SystemTap Tapsets<a class="headerlink" href="#systemtap-tapsets" title="Permalink to this headline">¶</a></h2>
  485. <p>The higher-level way to use the SystemTap integration is to use a “tapset”:
  486. SystemTap’s equivalent of a library, which hides some of the lower-level
  487. details of the static markers.</p>
  488. <p>Here is a tapset file, based on a non-shared build of CPython:</p>
  489. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>/*
  490. Provide a higher-level wrapping around the function__entry and
  491. function__return markers:
  492. \*/
  493. probe python.function.entry = process(&quot;python&quot;).mark(&quot;function__entry&quot;)
  494. {
  495. filename = user_string($arg1);
  496. funcname = user_string($arg2);
  497. lineno = $arg3;
  498. frameptr = $arg4
  499. }
  500. probe python.function.return = process(&quot;python&quot;).mark(&quot;function__return&quot;)
  501. {
  502. filename = user_string($arg1);
  503. funcname = user_string($arg2);
  504. lineno = $arg3;
  505. frameptr = $arg4
  506. }
  507. </pre></div>
  508. </div>
  509. <p>If this file is installed in SystemTap’s tapset directory (e.g.
  510. <code class="docutils literal notranslate"><span class="pre">/usr/share/systemtap/tapset</span></code>), then these additional probepoints become
  511. available:</p>
  512. <dl class="object">
  513. <dt class="sig sig-object">
  514. <span class="sig-name descname"><span class="pre">python.function.entry(str</span> <span class="pre">filename,</span> <span class="pre">str</span> <span class="pre">funcname,</span> <span class="pre">int</span> <span class="pre">lineno,</span> <span class="pre">frameptr)</span></span></dt>
  515. <dd><p>This probe point indicates that execution of a Python function has begun.
  516. It is only triggered for pure-Python (bytecode) functions.</p>
  517. </dd></dl>
  518. <dl class="object">
  519. <dt class="sig sig-object">
  520. <span class="sig-name descname"><span class="pre">python.function.return(str</span> <span class="pre">filename,</span> <span class="pre">str</span> <span class="pre">funcname,</span> <span class="pre">int</span> <span class="pre">lineno,</span> <span class="pre">frameptr)</span></span></dt>
  521. <dd><p>This probe point is the converse of <code class="docutils literal notranslate"><span class="pre">python.function.return</span></code>, and
  522. indicates that execution of a Python function has ended (either via
  523. <code class="docutils literal notranslate"><span class="pre">return</span></code>, or via an exception). It is only triggered for pure-Python
  524. (bytecode) functions.</p>
  525. </dd></dl>
  526. </section>
  527. <section id="examples">
  528. <h2>Examples<a class="headerlink" href="#examples" title="Permalink to this headline">¶</a></h2>
  529. <p>This SystemTap script uses the tapset above to more cleanly implement the
  530. example given above of tracing the Python function-call hierarchy, without
  531. needing to directly name the static markers:</p>
  532. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>probe python.function.entry
  533. {
  534. printf(&quot;%s =&gt; %s in %s:%d\n&quot;,
  535. thread_indent(1), funcname, filename, lineno);
  536. }
  537. probe python.function.return
  538. {
  539. printf(&quot;%s &lt;= %s in %s:%d\n&quot;,
  540. thread_indent(-1), funcname, filename, lineno);
  541. }
  542. </pre></div>
  543. </div>
  544. <p>The following script uses the tapset above to provide a top-like view of all
  545. running CPython code, showing the top 20 most frequently entered bytecode
  546. frames, each second, across the whole system:</p>
  547. <div class="highlight-none notranslate"><div class="highlight"><pre><span></span>global fn_calls;
  548. probe python.function.entry
  549. {
  550. fn_calls[pid(), filename, funcname, lineno] += 1;
  551. }
  552. probe timer.ms(1000) {
  553. printf(&quot;\033[2J\033[1;1H&quot;) /* clear screen \*/
  554. printf(&quot;%6s %80s %6s %30s %6s\n&quot;,
  555. &quot;PID&quot;, &quot;FILENAME&quot;, &quot;LINE&quot;, &quot;FUNCTION&quot;, &quot;CALLS&quot;)
  556. foreach ([pid, filename, funcname, lineno] in fn_calls- limit 20) {
  557. printf(&quot;%6d %80s %6d %30s %6d\n&quot;,
  558. pid, filename, lineno, funcname,
  559. fn_calls[pid, filename, funcname, lineno]);
  560. }
  561. delete fn_calls;
  562. }
  563. </pre></div>
  564. </div>
  565. </section>
  566. </section>
  567. <div class="clearer"></div>
  568. </div>
  569. </div>
  570. </div>
  571. <div class="sphinxsidebar" role="navigation" aria-label="main navigation">
  572. <div class="sphinxsidebarwrapper">
  573. <div>
  574. <h3><a href="../contents.html">Table of Contents</a></h3>
  575. <ul>
  576. <li><a class="reference internal" href="#">Instrumenting CPython with DTrace and SystemTap</a><ul>
  577. <li><a class="reference internal" href="#enabling-the-static-markers">Enabling the static markers</a></li>
  578. <li><a class="reference internal" href="#static-dtrace-probes">Static DTrace probes</a></li>
  579. <li><a class="reference internal" href="#static-systemtap-markers">Static SystemTap markers</a></li>
  580. <li><a class="reference internal" href="#available-static-markers">Available static markers</a></li>
  581. <li><a class="reference internal" href="#systemtap-tapsets">SystemTap Tapsets</a></li>
  582. <li><a class="reference internal" href="#examples">Examples</a></li>
  583. </ul>
  584. </li>
  585. </ul>
  586. </div>
  587. <div>
  588. <h4>Previous topic</h4>
  589. <p class="topless"><a href="clinic.html"
  590. title="previous chapter">Argument Clinic How-To</a></p>
  591. </div>
  592. <div>
  593. <h4>Next topic</h4>
  594. <p class="topless"><a href="perf_profiling.html"
  595. title="next chapter">Python support for the Linux <code class="docutils literal notranslate"><span class="pre">perf</span></code> profiler</a></p>
  596. </div>
  597. <div role="note" aria-label="source link">
  598. <h3>This Page</h3>
  599. <ul class="this-page-menu">
  600. <li><a href="../bugs.html">Report a Bug</a></li>
  601. <li>
  602. <a href="https://github.com/python/cpython/blob/main/Doc/howto/instrumentation.rst"
  603. rel="nofollow">Show Source
  604. </a>
  605. </li>
  606. </ul>
  607. </div>
  608. </div>
  609. </div>
  610. <div class="clearer"></div>
  611. </div>
  612. <div class="related" role="navigation" aria-label="related navigation">
  613. <h3>Navigation</h3>
  614. <ul>
  615. <li class="right" style="margin-right: 10px">
  616. <a href="../genindex.html" title="General Index"
  617. >index</a></li>
  618. <li class="right" >
  619. <a href="../py-modindex.html" title="Python Module Index"
  620. >modules</a> |</li>
  621. <li class="right" >
  622. <a href="perf_profiling.html" title="Python support for the Linux perf profiler"
  623. >next</a> |</li>
  624. <li class="right" >
  625. <a href="clinic.html" title="Argument Clinic How-To"
  626. >previous</a> |</li>
  627. <li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
  628. <li><a href="https://www.python.org/">Python</a> &#187;</li>
  629. <li class="switchers">
  630. <div class="language_switcher_placeholder"></div>
  631. <div class="version_switcher_placeholder"></div>
  632. </li>
  633. <li>
  634. </li>
  635. <li id="cpython-language-and-version">
  636. <a href="../index.html">3.12.0 Documentation</a> &#187;
  637. </li>
  638. <li class="nav-item nav-item-1"><a href="index.html" >Python HOWTOs</a> &#187;</li>
  639. <li class="nav-item nav-item-this"><a href="">Instrumenting CPython with DTrace and SystemTap</a></li>
  640. <li class="right">
  641. <div class="inline-search" role="search">
  642. <form class="inline-search" action="../search.html" method="get">
  643. <input placeholder="Quick search" aria-label="Quick search" type="search" name="q" />
  644. <input type="submit" value="Go" />
  645. </form>
  646. </div>
  647. |
  648. </li>
  649. <li class="right">
  650. <label class="theme-selector-label">
  651. Theme
  652. <select class="theme-selector" oninput="activateTheme(this.value)">
  653. <option value="auto" selected>Auto</option>
  654. <option value="light">Light</option>
  655. <option value="dark">Dark</option>
  656. </select>
  657. </label> |</li>
  658. </ul>
  659. </div>
  660. <div class="footer">
  661. &copy; <a href="../copyright.html">Copyright</a> 2001-2023, Python Software Foundation.
  662. <br />
  663. This page is licensed under the Python Software Foundation License Version 2.
  664. <br />
  665. Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
  666. <br />
  667. See <a href="/license.html">History and License</a> for more information.<br />
  668. <br />
  669. The Python Software Foundation is a non-profit corporation.
  670. <a href="https://www.python.org/psf/donations/">Please donate.</a>
  671. <br />
  672. <br />
  673. Last updated on Oct 02, 2023.
  674. <a href="/bugs.html">Found a bug</a>?
  675. <br />
  676. Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 4.5.0.
  677. </div>
  678. </body>
  679. </html>