Handbuch zur dynamischen Ablaufverfolgung in Solaris

Namensräume für Typen

Dieser Abschnitt befasst sich mit Namensräumen in D und Problemen in Bezug auf Namensräume für Typen. In herkömmlichen Sprachen wie ANSI-C ergibt sich die Typ-Sichtbarkeit daraus, ob ein Typ in eine Funktion oder eine andere Deklaration eingebettet ist. Im externen Gültigkeitsbereich eines C-Programms deklarierte Typen haben einen einzelnen, globalen Namensraum und sind im gesamten Programm sichtbar. Die in C-Definitionsdateien vereinbarten Typen werden in der Regel in diesen externen Gültigkeitsbereich aufgenommen. Im Gegensatz zu diesen Sprachen ermöglicht D den Zugriff auf Typen von mehreren externen Gültigkeitsbereichen.

Die Sprache D begünstigt die dynamische Beobachtungsfähigkeit über mehrere Ebenen eines Software-Stacks hinweg, einschließlich des Betriebssystemkernels, einer Gruppe ladbarer Kernelmodule und der auf dem System laufenden Benutzerprozesse. Ein einzelnes D-Programm kann Prüfpunkte zum Abrufen von Daten aus mehreren Kernelmodulen oder anderen Softwareeinheiten instanziieren, die in unabhängige binäre Objekte kompiliert werden. Aus diesem Grund ist es denkbar, dass in dem Universum der DTrace und dem D-Compiler zur Verfügung stehenden Typen mehrere Datentypen mit demselben Namen, möglicherweise mit unterschiedlichen Definitionen, vorliegen. Um dieser Situation Herr zu werden, verbindet der D-Compiler mit jedem Typ einen Namensraum, der in dem ihn enthaltenden Programmobjekt vereinbart ist. Typen aus einem bestimmten Programmobjekt können durch Angabe des Objektnamens und des Backquote-Operators (`) in einem beliebigen Typnamen angesprochen werden.

Wenn beispielsweise ein Kernelmodul namens foo die folgende C-Typdeklaration enthält:

typedef struct bar {
	int x;
} bar_t;

dann kann auf die Typen struct bar und bar_t aus D anhand der folgenden Typnamen zugegriffen werden:

struct foo`bar				foo`bar_t

Der Backquote-Operator kann in jedem Kontext verwendet werden, in dem ein Typname geeignet ist, einschließlich bei der Angabe des Typs für D-Variablendeklarationen oder ausdrückliche Typumwandlungen in D-Prüfpunktklauseln.

Der D-Compiler stellt auch zwei spezielle Namensräume für integrierte Typen, C und D, zur Verfügung. Der Namensraum für C-Typen wird anfänglich mit den ANSI-C-Standardtypen wie zum Beispiel int gefüllt. Darüber hinaus werden mit dem C-Preprozessor cpp(1) und der dtrace-Option -C erfasste Typdefinitionen von dem C-Gültigkeitsbereich verarbeitet und in ihn aufgenommen. Folglich können Sie C-Definitionsdateien aufnehmen, die bereits in einem anderen Typ-Namensraum sichtbare Typdeklarationen enthalten, ohne dadurch Kompilierungsfehler zu verursachen.

Der Namensraum für D-Typen wird anfänglich mit den D-internen Typen wie int und string und Typ-Aliasnamen wie uint32_t gefüllt. Neue Typdeklarationen, die im D-Programmcode vorkommen, werden automatisch dem Namensraum für D-Typen hinzugefügt. Wenn Sie in einem D-Programm einen komplexen Typ wie struct erzeugen, dessen Komponententypen aus anderen Namensräumen stammen, werden die Komponententypen durch die Deklaration in den D-Namensraum kopiert.

Sollte der D-Compiler auf eine Typdeklaration treffen, die keine explizite Namensraumangabe mit dem Backquote-Operator enthält, durchsucht der Compiler die Menge der aktiven Typ-Namensräume nach einer Entsprechung für den angegebenen Typnamen. Der C-Namensraum wird stets zuerst durchsucht. Danach erfolgt die Suche im D-Namensraum. Kann der Typname weder im C- noch im D-Namensraum gefunden werden, werden die Typ-Namensräume der aktiven Kernelmodule in aufsteigender Reihenfolge nach Kernelmodul-ID durchsucht. Diese Reihenfolge gewährleistet, dass die den inneren Kern bildenden binären Objekte vor etwaigen ladbaren Kernelmodulen durchsucht werden, garantiert aber keinerlei Reihenfolgeneigenschaften über die ladbaren Module hinaus. Benutzen Sie den Backquote-Operator für den Zugriff auf Typen, die in ladbaren Kernelmodulen definiert sind, um Typnamenskonflikte mit anderen Kernelmodulen zu vermeiden.

Für den automatischen Zugriff auf die Typen des Betriebssystemquellcodes stützt sich der D-Compiler auf komprimierte ANSI-C-Debugging-Informationen aus den zentralen Solaris-Kernelmodulen, sodass nicht auf die entsprechenden C-Include-Dateien zugegriffen werden muss. Diese symbolischen Debugging-Informationen stehen möglicherweise nicht für alle Kernelmodule auf dem System zur Verfügung. Bei dem Versuch, auf einen Typ im Namensraum eines Moduls ohne die für DTrace vorgesehenen komprimierten C-Debugging-Informationen zuzugreifen, gibt der D-Compiler einen Fehler aus.