<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/features.dtrace.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'features.dtrace.dtrace.php',
    1 => 'PHP и DTrace',
    2 => 'PHP и DTrace',
  ),
  'up' => 
  array (
    0 => 'features.dtrace.php',
    1 => 'Динамическая трассировка DTrace',
  ),
  'prev' => 
  array (
    0 => 'features.dtrace.introduction.php',
    1 => 'Введение в PHP и DTrace',
  ),
  'next' => 
  array (
    0 => 'features.dtrace.systemtap.php',
    1 => 'Работа средства SystemTap со статическими зондами PHP DTrace',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'features/dtrace.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="features.dtrace.dtrace" class="sect1">
  <h2 class="title">PHP и DTrace</h2>
  <p class="para">
   PHP конфигурируется со статическими зондами
   DTrace на платформах, которые поддерживают динамическую
   трассировку DTrace.
  </p>

  <div class="sect2" id="features.dtrace.install">
   <h3 class="title">Конфигурирование PHP со статическими зондами DTrace</h3>

   <p class="para">
    Обратитесь к документации платформы, чтобы
    включить поддержку DTrace в операционной системе.
    Например, в Oracle Linux требуется загрузить ядро UEK3
    и сделать следующее:

    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"># modprobe fasttrap<br /># chmod 666 /dev/dtrace/helper</span></code></div>
     </div>

    </div>
   </p>
   <p class="para">
    Вместо <code class="literal">chmod</code> доступен
    пакет правил ACL для ограничения доступа для конкретного
    пользователя.
   </p>

   <p class="para">
    Сборка PHP с ключом <code class="literal">--enable-dtrace</code>:
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"># ./configure --enable-dtrace ...<br /># make<br /># make install</span></code></div>
     </div>

    </div>
   </p>
   <p class="para">
    Это делает статические зонды доступными в ядре PHP. Любой
    модуль PHP, который предоставляет свои зонды,
    потребуется собрать отдельно как разделяемый модуль.
   </p>
   <p class="para">
    Установите переменную среды <strong class="option unknown">USE_ZEND_DTRACE=1</strong> для целевых PHP-процессов, чтобы включить зонды.
   </p>
  </div>

  <div class="sect2" id="features.dtrace.static-probes">
   <h3 class="title">Статические зонды DTrace в ядре PHP</h3>
   <table class="doctable table">
    <caption><strong>Следующие статические зонды доступны в PHP</strong></caption>
    
     <thead>
      <tr>
       <th>Название зонда</th>
       <th>Описание зонда</th>
       <th>Аргументы зонда</th>
      </tr>

     </thead>

     <tbody class="tbody">
      <tr>
       <td><code class="literal">request-startup</code></td>
       <td>Срабатывает при начале запроса.</td>
       <td>char *<var class="varname">file</var>, char *<var class="varname">request_uri</var>, char *<var class="varname">request_method</var></td>
      </tr>

      <tr>
       <td><code class="literal">request-shutdown</code></td>
       <td>Срабатывает при окончании запроса.</td>
       <td>char *<var class="varname">file</var>, char *<var class="varname">request_uri</var>, char *<var class="varname">request_method</var></td>
      </tr>

      <tr>
       <td><code class="literal">compile-file-entry</code></td>
       <td>Срабатывает, когда начинается компиляция скрипта.</td>
       <td>char *<var class="varname">compile_file</var>, char *<var class="varname">compile_file_translated</var></td>
      </tr>

      <tr>
       <td><code class="literal">compile-file-return</code></td>
       <td>Срабатывает, когда заканчивается компиляция скрипта.</td>
       <td>char *<var class="varname">compile_file</var>, char *<var class="varname">compile_file_translated</var></td>
      </tr>

      <tr>
       <td><code class="literal">execute-entry</code></td>
       <td>Срабатывает, когда запускается массив байт-кода. К примеру, когда вызываются функции, возобновляется работа генератора или происходит include.</td>
       <td>char *<var class="varname">request_file</var>, int <var class="varname">lineno</var></td>
      </tr>

      <tr>
       <td><code class="literal">execute-return</code></td>
       <td>Срабатывает, после отработки массива байт-кода.</td>
       <td>char *<var class="varname">request_file</var>, int <var class="varname">lineno</var></td>
      </tr>

      <tr>
       <td><code class="literal">function-entry</code></td>
       <td>Срабатывает, когда движок PHP начинает запуск функции или метода.</td>
       <td>char *<var class="varname">function_name</var>, char *<var class="varname">request_file</var>, int <var class="varname">lineno</var>, char *<var class="varname">classname</var>, char *<var class="varname">scope</var></td>
      </tr>

      <tr>
       <td><code class="literal">function-return</code></td>
       <td>Срабатывает, когда движок PHP возвращается из функции или метода.</td>
       <td>char *<var class="varname">function_name</var>, char *<var class="varname">request_file</var>, int <var class="varname">lineno</var>, char *<var class="varname">classname</var>, char *<var class="varname">scope</var></td>
      </tr>

      <tr>
       <td><code class="literal">exception-thrown</code></td>
       <td>Срабатывает, когда выброшено исключение.</td>
       <td>char *<var class="varname">classname</var></td>
      </tr>

      <tr>
       <td><code class="literal">exception-caught</code></td>
       <td>Срабатывает, когда исключение поймано.</td>
       <td>char *<var class="varname">classname</var></td>
      </tr>

      <tr>
       <td><code class="literal">error</code></td>
       <td>Срабатывает, если возникла ошибка, независимо от уровня <a href="errorfunc.configuration.php#ini.error-reporting" class="link">error_reporting</a>.</td>
       <td>char *<var class="varname">errormsg</var>, char *<var class="varname">request_file</var>, int <var class="varname">lineno</var></td>
      </tr>

     </tbody>
    
   </table>

   <p class="para">
    Модули PHP могут содержать дополнительные зонды.
   </p>
  </div>

  <div class="sect2" id="features.dtrace.list-probes">
   <h3 class="title">Список статических зондов DTrace в PHP</h3>
   <p class="para">
    Запустите PHP-процесс и выполните следующую команду, чтобы получить список зондов:
    <div class="informalexample">
     <div class="example-contents">
<div class="cdata"><pre>
# dtrace -l
</pre></div>
     </div>

    </div>
   </p>

   <p class="para">
    Команда выведет примерно следующее:
    <div class="informalexample">
     <div class="example-contents">
<div class="cdata"><pre>
   ID   PROVIDER            MODULE                          FUNCTION NAME
   [ . . . ]
    4   php15271               php               dtrace_compile_file compile-file-entry
    5   php15271               php               dtrace_compile_file compile-file-return
    6   php15271               php                        zend_error error
    7   php15271               php  ZEND_CATCH_SPEC_CONST_CV_HANDLER exception-caught
    8   php15271               php     zend_throw_exception_internal exception-thrown
    9   php15271               php                 dtrace_execute_ex execute-entry
   10   php15271               php           dtrace_execute_internal execute-entry
   11   php15271               php                 dtrace_execute_ex execute-return
   12   php15271               php           dtrace_execute_internal execute-return
   13   php15271               php                 dtrace_execute_ex function-entry
   14   php15271               php                 dtrace_execute_ex function-return
   15   php15271               php              php_request_shutdown request-shutdown
   16   php15271               php               php_request_startup request-startup
</pre></div>
     </div>

    </div>
   </p>

   <p class="para">
    Колонка Provider содержит надпись <code class="literal">php</code>
    и PID-идентификатор текущего запущенного PHP-процесса.
   </p>

   <p class="para">
    При работе веб-сервера Apache название модуля выводится как,
    например, <var class="filename">libphp5.so</var>, и выводятся
    серия блоков списка, по одному на каждый процесс Apache.
   </p>

   <p class="para">
    Колонка Function ссылается на название внутренней С-функции PHP,
    которая реализует соответствующий зонд.
   </p>

   <p class="para">
    Список не будет содержать зонды, которые связаны с PHP, если PHP не запустили.
   </p>
  </div>

  <div class="sect2" id="features.dtrace.examples">
   <h3 class="title">Примеры работы DTrace с PHP</h3>
   <p class="para">
    Пример показывает базовые возможности скриптового языка DTrace D.
    <div class="example" id="example-1">
     <p><strong>Пример #1 Скрипт <var class="filename">all_probes.d</var> — трассировка статических PHP-зондов через DTrace</strong></p>
     <div class="example-contents">
<div class="cdata"><pre>
#!/usr/sbin/dtrace -Zs

#pragma D option quiet

php*:::compile-file-entry
{
    printf(&quot;PHP compile-file-entry\n&quot;);
    printf(&quot;  compile_file              %s\n&quot;, copyinstr(arg0));
    printf(&quot;  compile_file_translated   %s\n&quot;, copyinstr(arg1));
}

php*:::compile-file-return
{
    printf(&quot;PHP compile-file-return\n&quot;);
    printf(&quot;  compile_file              %s\n&quot;, copyinstr(arg0));
    printf(&quot;  compile_file_translated   %s\n&quot;, copyinstr(arg1));
}

php*:::error
{
    printf(&quot;PHP error\n&quot;);
    printf(&quot;  errormsg                  %s\n&quot;, copyinstr(arg0));
    printf(&quot;  request_file              %s\n&quot;, copyinstr(arg1));
    printf(&quot;  lineno                    %d\n&quot;, (int)arg2);
}

php*:::exception-caught
{
    printf(&quot;PHP exception-caught\n&quot;);
    printf(&quot;  classname                 %s\n&quot;, copyinstr(arg0));
}

php*:::exception-thrown
{
    printf(&quot;PHP exception-thrown\n&quot;);
    printf(&quot;  classname                 %s\n&quot;, copyinstr(arg0));
}

php*:::execute-entry
{
    printf(&quot;PHP execute-entry\n&quot;);
    printf(&quot;  request_file              %s\n&quot;, copyinstr(arg0));
    printf(&quot;  lineno                    %d\n&quot;, (int)arg1);
}

php*:::execute-return
{
    printf(&quot;PHP execute-return\n&quot;);
    printf(&quot;  request_file              %s\n&quot;, copyinstr(arg0));
    printf(&quot;  lineno                    %d\n&quot;, (int)arg1);
}

php*:::function-entry
{
    printf(&quot;PHP function-entry\n&quot;);
    printf(&quot;  function_name             %s\n&quot;, copyinstr(arg0));
    printf(&quot;  request_file              %s\n&quot;, copyinstr(arg1));
    printf(&quot;  lineno                    %d\n&quot;, (int)arg2);
    printf(&quot;  classname                 %s\n&quot;, copyinstr(arg3));
    printf(&quot;  scope                     %s\n&quot;, copyinstr(arg4));
}

php*:::function-return
{
    printf(&quot;PHP function-return\n&quot;);
    printf(&quot;  function_name             %s\n&quot;, copyinstr(arg0));
    printf(&quot;  request_file              %s\n&quot;, copyinstr(arg1));
    printf(&quot;  lineno                    %d\n&quot;, (int)arg2);
    printf(&quot;  classname                 %s\n&quot;, copyinstr(arg3));
    printf(&quot;  scope                     %s\n&quot;, copyinstr(arg4));
}

php*:::request-shutdown
{
    printf(&quot;PHP request-shutdown\n&quot;);
    printf(&quot;  file                      %s\n&quot;, copyinstr(arg0));
    printf(&quot;  request_uri               %s\n&quot;, copyinstr(arg1));
    printf(&quot;  request_method            %s\n&quot;, copyinstr(arg2));
}

php*:::request-startup
{
    printf(&quot;PHP request-startup\n&quot;);
    printf(&quot;  file                      %s\n&quot;, copyinstr(arg0));
    printf(&quot;  request_uri               %s\n&quot;, copyinstr(arg1));
    printf(&quot;  request_method            %s\n&quot;, copyinstr(arg2));
}
</pre></div>
     </div>

    </div>
   </p>

   <p class="para">
    Скрипт указывает опцию <code class="literal">-Z</code>
    для команды <var class="filename">dtrace</var>, разрешая работать даже
    если ни однин PHP-процесс не запущен. Без этой опции
    скрипт сразу же завершит выполнение, поскольку
    не увидит ни одного зонда, который требуется отслеживать.
   </p>

   <p class="para">
    Скрипт отслеживает каждый статический PHP-зонд на всём
    протяжении работы PHP-скрипта.
    Запускаем D-скрипт:
    <div class="informalexample">
     <div class="example-contents">
<div class="cdata"><pre>
# ./all_probes.d
</pre></div>
     </div>

    </div>
   </p>

   <p class="para">
    Запустите скрипт или PHP-приложение. Отслеживающий D-скрипт
    будет выводить аргументы каждого сработавшего зонда.
   </p>

   <p class="para">
    После получения информации работу скрипта
    прерывают комбинацией <kbd class="keycombo"><kbd class="keycap">CTRL</kbd>+<kbd class="keycap">C</kbd></kbd>.
   </p>

   <p class="para">
    На многопроцессорных машинах порядок зондов
    непоследователен и зависит от процессоров,
    на которых работают зонды и как мигрируют потоки между процессорами.
    Отображение временных меток помогает избегать конфузов.
    К примеру:
    <div class="informalexample">
     <div class="example-contents">
<div class="cdata"><pre>
php*:::function-entry
{
      printf(&quot;%lld: PHP function-entry &quot;, walltimestamp);
      [ . . .]
}
</pre></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect2" id="features.dtrace.references">
   <h3 class="title">Смотрите также</h3>
   <ul class="simplelist">
    <li><a href="oci8.dtrace.php" class="link">OCI8 и динамическая трассировка DTrace</a></li>
   </ul>
  </div>
 </div><?php manual_footer($setup); ?>