<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
<!--
Recently I suggested to myself that this should become a profiling
and debugging chapter, which covers things like ktrace(1) and
using other debugging (like -x in shell scripts).  But then I
realized that, over time and while DTrace becomes better supported,
that might make this chapter too large.
-->

<!--
     The FreeBSD Documentation Project
     $FreeBSD$
     $FreeBSDde: de-docproj/books/handbook/dtrace/chapter.sgml,v 1.4 2009/08/22 18:54:15 bcr Exp $
     basiert auf: 1.8
-->

<chapter id="dtrace">
  <chapterinfo>
    <authorgroup>
      <author>
	<firstname>Tom</firstname>
	<surname>Rhodes</surname>
	<contrib>Written by </contrib>
      </author>
    </authorgroup>

    <authorgroup>
      <author>
	<firstname>Benedict</firstname>
	<surname>Reuschling</surname>
	<contrib>Übersetzt von </contrib>
      </author>
      <author>
	<firstname>Christoph</firstname>
	<surname>Sold</surname>
      </author>
    </authorgroup>
  </chapterinfo>

  <title>&dtrace;</title>

  <sect1 id="dtrace-synopsis">
    <title>Überblick</title>

    <indexterm><primary>&dtrace;</primary></indexterm>
    <indexterm>
      <primary>&dtrace; support</primary>
      <see>&dtrace;</see>
    </indexterm>

    <para>&dtrace;, auch bekannt als Dynamic Tracing, wurde von &sun; als ein
      Werkzeug zur Analyse von Performance-Problemen in Produktiv- und
      Entwicklungssystemen entwickelt.  Es ist kein Debugging-Werkzeug, sondern
      ein Hilfsmittel für Echtzeit-Systemanalysen.</para>

    <para>&dtrace; ist ein bemerkenswertes Werkzeug zur Profilerstellung, mit
      einer beeindruckenden Palette von Eigenschaften zur Diagnose von
      Systemereignissen.  Es kann auch dazu verwendet werden, bestehende
      Skripte ablaufen zu lassen, um einen Nutzen aus deren Möglichkeiten
      zu ziehen.  Nutzer können mittels der Programmiersprache D von
      &dtrace; ihre eigenen Hilfsmittel schreiben, was es ermöglicht, die
      eigenen Profile nach Ihren Bedürfnissen anzupassen.</para>

    <para>Nachdem Sie dieses Kapitel gelesen haben, werden Sie Folgendes wissen:</para>

    <itemizedlist>
      <listitem>
	<para>Was &dtrace; ist und welche Funktionen es zur Verfügung
	  stellt.</para>
      </listitem>

      <listitem>
	<para>Unterschiede zwischen der &solaris; &dtrace; Implementierung und
	  derjenigen, die &os; bereitstellt.</para>
      </listitem>

      <listitem>
	<para>Wie man &dtrace; auf &os; aktiviert und verwendet.</para>
      </listitem>
    </itemizedlist>

    <para>Bevor Sie dieses Kapitel lesen, sollten Sie:</para>

    <itemizedlist>
      <listitem>
	<para>&unix; und &os; Grundlagen verstehen (<xref
	  linkend="basics"/>).</para>
      </listitem>

      <listitem>
	<para>Einen Kernel konfigurieren und kompilieren können (<xref
	  linkend="kernelconfig"/>).</para>
      </listitem>

      <listitem>
	<para>Vertraut sein mit Sicherheitsaspekten und wie diese
	  &os; betreffen (<xref linkend="security"/>).</para>
      </listitem>

      <listitem>
	<para>Verstehen, wie man den Quellcode von &os; beziehen und das
	  Betriebssystem neu erstellen kann (<xref
	  linkend="updating-upgrading"/>).</para>
      </listitem>
    </itemizedlist>

    <!--
      Temporary warning to avoid listing experimental versions
      and production versions of FreeBSD with this technology.
    -->
    <warning>
      <para>Diese Funktion ist als experimentell anzusehen.  Manche
        Einstellungen enthalten möglicherweise nicht alle
        Funktionalitäten, andere Teile könnten gar nicht laufen.  Mit
        der Zeit, wenn diese Funktion als für den Produktivbetrieb
        geeignet erscheint, wird auch diese Dokumentation geändert, um
        diesem Umstand gerecht zu werden.</para>
    </warning>
  </sect1>

  <sect1 id="dtrace-implementation">
    <title>Unterschiede in der Implementierung</title>

    <para>Obwohl &dtrace; in &os; sehr ähnlich zu dem in &solaris; ist,
      existieren doch Unterschiede, die vorher erklärt werden müssen.
      Der Hauptunterschied für die Anwender besteht darin, dass in &os;
      &dtrace; explizit aktiviert werden muss.  Es existieren Kerneloptionen
      und Module, die aktiviert sein müssen, damit &dtrace; korrekt
      arbeitet.  Diese werden später genauer erlätert.</para>

    <para>Die Kerneloption <literal>DDB_CTF</literal> wird dafür
      verwendet, um die Unterstützung im Kernel für das Laden von
      <acronym>CTF</acronym>-Daten aus Kernelmodulen und dem Kernel selbst zu
      ermöglichen.  <acronym>CTF</acronym> ist das Compact C Type Format
      von &solaris;, welches eine reduzierte Form von Debug-Informationen
      kapselt, ähnlich zu <acronym>DWARF</acronym> und den antiken Stabs.
      Diese <acronym>CTF</acronym>-Daten werden dem Binärcode von den
      <command>ctfconvert</command> und <command>ctfmerge</command> Befehlen
      den Werkzeugen zum Bauen des Systems hinzugefügt.  Das
      <command>ctfconvert</command>-Dienstprogramm parst die vom Compiler
      erstellten <acronym>DWARF</acronym> <acronym>ELF</acronym>
      Debug-Abschnitte und <command>ctfmerge</command> vereint
      <acronym>CTF</acronym> <acronym>ELF</acronym>-Abschnitte aus Objekten,
      entweder in ausführbare Dateien oder Shared-Libraries.  In
      Kürze erfahren Sie, wie Sie dies für den Kernel und den Bau von
      &os; aktivieren.</para>

    <para>Einige Provider in &os; unterscheiden sich von der
      &solaris;-Implementierung.  Am deutlichsten wird das beim
      <literal>dtmalloc</literal>-Provider, welcher das Aufzeichnen von
      <function>malloc()</function> nach Typen im &os;-Kernel
      ermöglicht.</para>

    <para>In &os; darf &dtrace; wegen unterschiedlicher Sicherheitskonzepte
      nur von <username>root</username> verwendet werden.  &solaris;
      besitzt ein paar Audit-Funktionen auf den unteren Ebenen, die noch nicht
      in &os; implementiert sind.  Deshalb kann nur <username>root</username>
      auf <devicename>/dev/dtrace/dtrace</devicename> zugreifen.</para>

    <para>Zum Schluss muss noch erwähnt werden, dass die &dtrace;-Software
      unter &sun;s <acronym>CDDL</acronym> Lizenz fällt.  Die
      <literal>Common Development and Distribution License</literal> wird von
      &os; mitgeliefert, sehen Sie sich dazu
      <filename>/usr/src/cddl/contrib/opensolaris/OPENSOLARIS.LICENSE</filename>
      an, oder lesen Sie die Online-Version unter <ulink
      url="http://www.opensolaris.org/os/licensing"></ulink>.</para>

    <para>Diese Lizenz bedeutet, dass ein &os;-Kernel mit den &dtrace;-Optionen
      immer noch <acronym>BSD</acronym>-lizenziert ist; allerdings tritt die
      <acronym>CDDL</acronym> in Kraft, wenn Module in Binärform
      vertrieben werden oder die Binärdateien geladen werden.</para>
  </sect1>

  <sect1 id="dtrace-enable">
    <title>Die &dtrace; Unterstützung aktivieren</title>

    <para>Um Unterstützung für &dtrace; zu aktivieren, fügen Sie
	  die folgenden Zeilen zu Ihrer Kernelkonfigurationsdatei hinzu:</para>

    <programlisting>options         KDTRACE_HOOKS
options         DDB_CTF</programlisting>

    <note>
      <para>Besitzer der AMD-Architektur werden wahrscheinlich noch die
        folgende Zeile zur Kernelkonfigurationsdatei hinzufügen:</para>

      <programlisting>options         KDTRACE_FRAME</programlisting>

      <para>Diese Option liefert die Unterstützung für die
        <acronym>FBT</acronym>-Eigenschaft.  &dtrace; wird auch ohne diese
        Option funktionieren; jedoch wird dann Function Boundary Tracing nur
        eingeschränkt unterstützt.</para>
      </note>

    <para>Der gesamte Quellcode muss neu gebaut und mit der
      <acronym>CTF</acronym>-Option installiert werden.  Um das zu erreichen,
      bauen Sie &os; aus dem Quellcode mittels:</para>

    <!-- XXXTR: WITH_CTF has been reported to leave a user with a
         broken system when used with buildworld.  Until this is
         fixed, comment out those parts.  When uncommenting, kill
         the extra screen.
    -->

    <screen>&prompt.root; <userinput>cd /usr/src</userinput>
<!-- &prompt.root; <userinput>make WITH_CTF=1 buildworld</userinput> -->
&prompt.root; <userinput>make WITH_CTF=1 kernel</userinput></screen>
<!-- &prompt.root; <userinput>make WITH_CTF=1 installworld</userinput>
&prompt.root; <userinput>mergemaster -Ui</userinput></screen> -->

    <para>Das System muss im Anschluss daran neu gestartet werden.</para>

    <para>Nachdem das System neu gestartet und der neue Kernel in den
      Hauptspeicher geladen wurde, sollte die Unterstützung für die
      Korn-Shell hinzugefügt werden.  Dies wird benötigt, da die
      Sammlung von &dtrace;-Werkzeugen mehrere Dienstprogramme enthält,
      die in <command>ksh</command> implementiert sind.  Installieren Sie
      <filename role="package">shells/ksh93</filename>.  Es ist auch
      möglich, diese Werkzeuge unter <filename
      role="package">shells/pdksh</filename> oder <filename
      role="package">shells/mksh</filename> laufen zu lassen.</para>

    <para>Zum Schluss sollten Sie noch den aktuellen &dtrace;-Werkzeugsatz
      beschaffen.  Die aktuelle Version ist unter <ulink
      url="http://www.opensolaris.org/os/community/dtrace/dtracetoolkit/"></ulink>
      verfügbar.  Ein Mechanismus zur Installation ist enthalten,
      allerdings ist eine Installation nicht unbedingt nötig, um die darin
      enthaltenen Dienstprogramme einzusetzen.</para>
  </sect1>

  <sect1 id="dtrace-using">
    <title>&dtrace; verwenden</title>

    <para>Bevor die &dtrace;-Funktionaltät benutzt werden kann, muss das
      &dtrace;-Gerät existieren.  Um das Gerät zu laden, geben Sie
      das folgende Kommando ein:</para>

    <screen>&prompt.root; <userinput>kldload dtraceall</userinput></screen>

    <para>Die &dtrace;-Unterstützung sollte jetzt verfügbar sein.  Um
      alle Sonden anzuzeigen, kann der Administrator nun den folgenden Befehl
      eingeben:</para>

    <screen>&prompt.root; <userinput>dtrace -l | more</userinput></screen>

    <para>Alle Ausgaben werden an das <command>more</command>-Programm
      übergeben, da der Bildschirmpuffer sehr schnell überlaufen
      wird.  Ab diesem Punkt kann &dtrace; als einsatzbereit angesehen werden.
      Jetzt ist es an der Zeit, sich näher mit dem Satz von Werkzeugen zu
      beschäftigen.</para>

    <para>Der Werkzeugsatz ist eine Sammlung von vorgefertigten Skripten, die
      von &dtrace; ausgeführt werden können, um Systeminformationen
      zu sammeln.  Es gibt Skripte, die offene Dateien überprüfen,
      den Speicher, <acronym>CPU</acronym>-Verbrauch und noch viel mehr.
      Entpacken Sie die Skripte mit dem folgenden Befehl:</para>

    <screen>&prompt.root; <userinput>gunzip -c DTraceToolkit* | tar xvf -</userinput></screen>

    <para>Wechseln Sie mit dem <command>cd</command>-Kommando in dieses
      Verzeichnis und ändern Sie die Berechtigung zum Ausführen von
      allen Dateien, deren Name klein geschrieben ist, auf
      <literal>755</literal>.</para>

    <para>All diese Skripte müssen inhaltlich verändert werden.
      Diejenigen, die auf <filename>/usr/bin/ksh</filename> verweisen,
      müssen in <filename>/usr/local/bin/ksh</filename> geändert
      werden und die Anderen, welche <filename>/usr/bin/sh</filename>
      verwenden, müssen so angepasst werden, dass sie
      <filename>/bin/sh</filename> verwenden.  Schliesslich müssen noch
      diejenigen, die <filename>/usr/bin/perl</filename> enthalten, auf
      <filename>/usr/local/bin/perl</filename> umgeschrieben werden.</para>

    <important>
      <para>Zu diesem Zeitpunkt ist es klug, den Leser noch einmal daran zu
        erinnern, dass die Unterstützung von &dtrace; in &os; noch
        <emphasis>unvollständig</emphasis> und
        <emphasis>experimentell</emphasis> ist.  Viele dieser Skripte werden
        nicht funktionieren, da diese entweder zu sehr &solaris;-spezifisch
        sind oder Sonden verwenden, die zur Zeit noch nicht unterstützt
        werden.</para>
    </important>

    <para>Zum Zeitpunkt, an dem dieses Dokument geschrieben wurde, existieren
      nur zwei Skripte im &dtrace;-Werkzeugsatz, die von &os; komplett
      unterstützt werden: die Skripte <filename>hotkernel</filename> und
      <filename>procsystime</filename>.  Diese beiden werden in den folgenden
      Teilen dieses Abschnitts genauer untersucht.</para>

    <para><filename>hotkernel</filename> wurde entworfen, um zu identifizieren,
      welche Funktion die meiste Kernelzeit beansprucht.  Normal
      ausgeführt, wird es Ausgaben ähnlich der Folgenden
      produzieren:</para>

    <screen>&prompt.root; <userinput>./hotkernel</userinput>
Sampling... Hit Ctrl-C to end.</screen>

    <para>Der Systemadministrator muss die Tastenkombination <keycombo
      action="simul"><keycap>Ctrl</keycap><keycap>C</keycap></keycombo>
      drücken, um den Prozess zu stoppen.  Nach dem Abbruch wird das
      Skript eine Liste von Kernelfunktionen und Zeitmessungen ausgeben,
      aufsteigend sortiert nach den Zeiten:</para>

    <screen>kernel`_thread_lock_flags                                   2   0.0%
0xc1097063                                                  2   0.0%
kernel`sched_userret                                        2   0.0%
kernel`kern_select                                          2   0.0%
kernel`generic_copyin                                       3   0.0%
kernel`_mtx_assert                                          3   0.0%
kernel`vm_fault                                             3   0.0%
kernel`sopoll_generic                                       3   0.0%
kernel`fixup_filename                                       4   0.0%
kernel`_isitmyx                                             4   0.0%
kernel`find_instance                                        4   0.0%
kernel`_mtx_unlock_flags                                    5   0.0%
kernel`syscall                                              5   0.0%
kernel`DELAY                                                5   0.0%
0xc108a253                                                  6   0.0%
kernel`witness_lock                                         7   0.0%
kernel`read_aux_data_no_wait                                7   0.0%
kernel`Xint0x80_syscall                                     7   0.0%
kernel`witness_checkorder                                   7   0.0%
kernel`sse2_pagezero                                        8   0.0%
kernel`strncmp                                              9   0.0%
kernel`spinlock_exit                                       10   0.0%
kernel`_mtx_lock_flags                                     11   0.0%
kernel`witness_unlock                                      15   0.0%
kernel`sched_idletd                                       137   0.3%
0xc10981a5                                              42139  99.3%</screen>

    <!-- XXXTR: I attempted to use objdump and nm on /boot/kernel/kernel
        to find 0xc10981a5, but to no avail.  It would be nice to know
	how we should look that up. -->

    <para>Dieses Skript funktioniert auch mit Kernelmodulen.  Um diese
      Eigenschaft zu verwenden, starten Sie das Skript mit dem Parameter
      <option>-m</option>:</para>

    <screen>&prompt.root; <userinput>./hotkernel -m</userinput>
Sampling... Hit Ctrl-C to end.
^C
MODULE                                                  COUNT   PCNT
0xc107882e                                                  1   0.0%
0xc10e6aa4                                                  1   0.0%
0xc1076983                                                  1   0.0%
0xc109708a                                                  1   0.0%
0xc1075a5d                                                  1   0.0%
0xc1077325                                                  1   0.0%
0xc108a245                                                  1   0.0%
0xc107730d                                                  1   0.0%
0xc1097063                                                  2   0.0%
0xc108a253                                                 73   0.0%
kernel                                                    874   0.4%
0xc10981a5                                             213781  99.6%</screen>

    <!-- XXXTR: I was unable to match these up with output from
        kldstat and kldstat -v and grep.  Maybe I'm missing something
	seriously obvious.  It is 5AM btw. -->

    <para>Das <filename>procsystime</filename> Skript fängt die
      Systemaufruf-Zeiten ab und zeigt diese für eine gegebene
      <acronym>PID</acronym> oder einen Prozessnamen an.  Im folgenden Beispiel
      wurde eine neue Instanz von <filename>/bin/csh</filename> erzeugt.
      <filename>procsystime</filename> wurde ausgeführt und verbleibt so,
      während ein paar Befehle in die andere Instanz von
      <command>csh</command> eingegeben werden.  Dies sind die Ergebnisse
      dieses Versuchs:</para>

    <screen>&prompt.root; <userinput>./procsystime -n csh</userinput>
Tracing... Hit Ctrl-C to end...
^C

Elapsed Times for processes csh,

         SYSCALL          TIME (ns)
          getpid               6131
       sigreturn               8121
           close              19127
           fcntl              19959
             dup              26955
         setpgid              28070
            stat              31899
       setitimer              40938
           wait4              62717
       sigaction              67372
     sigprocmask             119091
    gettimeofday             183710
           write             263242
          execve             492547
           ioctl             770073
           vfork            3258923
      sigsuspend            6985124
            read         3988049784</screen>

    <para>Wie aus der Ausgabe ersichtlich ist, verbraucht der
      <function>read()</function>-Systemaufruf die meiste Zeit in Nanosekunden,
      während der Systemaufruf <function>getpid()</function> hingegen am
      schnellsten läft.</para>
  </sect1>

  <sect1 id="dtrace-language">
    <title>Die Sprache D</title>

    <para>Der &dtrace; Werkzeugsatz enthält viele Skripte in der
      speziellen Sprache von &dtrace;.  Diese Sprache wird als <quote>die D
      Sprache</quote> in der Dokumentation von &sun; bezeichnet und ist C++
      sehr ähnlich.  Eine tiefergehende Betrachtung dieser Sprache
      würde den Rahmen dieses Dokuments sprengen.  Ausführlich wird
      diese Sprache unter <ulink
      url="http://wikis.sun.com/display/DTrace/Documentation"></ulink>
      behandelt.</para>
  </sect1>
</chapter>

    <!-- XXXTR: Should probably put links and resources here.  I'm
        nervous about this chapter as it may require a partial
	re-write and large modification once DTrace is complete, but
	at least we can get everyone started ... -->