# DLL-Konflikt

Der Ausdruck DLL-Konflikt (auch DLL Hell, deutsch: „DLL-Hölle“ genannt) bezeichnet ein Problem, das durch die Installation von Dynamic Link Library (DLLs) auf den Betriebssystemen der Windows-Reihe entstehen kann. Vorwiegend sind ältere Windowsversionen betroffen, da diese nur beschränkte Möglichkeiten besitzen, um System-Dateien und DLL-Bibliotheken zu verwalten. Auch bei älteren Versionen von Mac OS treten ähnliche Probleme auf, die als Extension Conflicts (Erweiterungskonflikte) bezeichnet werden. In den verschiedenen Linux-Distributionen werden Bibliothekskonflikte meist durch den distributionseigenen Paketmanager verhindert, jedoch nicht immer.

## Das Problem

Grundsätzlich erlauben DLLs Computerprogrammen, auf ihren Programmcode und ihre Ressourcen zuzugreifen, um so identischen Code, den sonst jedes Programm selbst mitbringen müsste, zusammenzufassen. Jedoch bringen neue Programme oft neue Versionen einer bereits vorhandenen DLL (Shared Library) mit. Nun hat das Programm die Wahl, ob es bei der Installation die alte DLL überschreibt (was aber zu Kompatibilitätsproblemen mit anderen Programmen führen kann) oder eine weitere Kopie auf dem System installiert.
Virtueller Speicher ermöglicht der Prozessverwaltung eines Betriebssystems, weite Teile gemeinsam benutzter Bibliotheken in gemeinsam verwendeten Seiten physischen Speichers abzulegen. Wenn viele Programme dieselbe Bibliothek verwenden, wird der gesamte Speicherbedarf damit deutlich kleiner als die Summe aller Prozesse. Dieses Verfahren setzt voraus, dass es sich um dieselbe Datei, nicht nur um einen identischen Inhalt handelt. Mehrere verwendete Kopien der gleichen Bibliothek benötigen daher nicht nur zusätzlichen Festplattenspeicher, sondern auch mehr Arbeitsspeicher.
Je mehr alte und neue Programme gemeinsam verwendet werden, desto höher ist das Risiko für das Auftreten von DLL-Konflikten. Das kann zu einer unüberschaubaren Menge verschiedener DLL-Dateien führen, die zum Teil vom Betriebssystem selbst benötigt werden (und deshalb auf keinen Fall entfernt werden dürfen), zum Teil aber auch unbenötigte Reste gelöschter Installationen darstellen.
Auf modernen Systemen kann zwar davon ausgegangen werden, dass die verfügbare Festplattenkapazität durch redundante DLL-Versionen kaum beeinträchtigt sein wird. Jedoch stellt, ähnlich wie bei verwaisten Einträgen in der Systemregistrierung, alleine die Tatsache, dass das System immer chaotischer wird und somit unbegründet Rechenleistung verbraucht sowie potenzielle Instabilitäten erzeugt, ein grundsätzliches Problem dar.

### Ursachen

DLLs werden von verschiedenen Programmen in unterschiedlichen Versionen benötigt, früher aber in der Regel an zentraler Stelle im Windows- oder Systemverzeichnis abgelegt und im Falle von COM-DLLs in der Windows-Registrierungsdatenbank eingetragen. Das spart Speicherplatz und kann die Programmausführung deutlich beschleunigen, da das System weniger Zeit benötigt, um die für das Programm jeweils richtige DLL-Version zu finden. Andererseits kann die Installation eines neuen Programms dazu führen, dass eine neue DLL die alte Version überschreibt. Die neue Version kann eventuell bei der älteren Software aufgrund einer schlechten oder ungenauen Spezifikation der Schnittstelle oder einer falschen Nutzung der Programmierschnittstelle Kompatibilitätsprobleme verursachen. Das ist ein Zeichen mangelhaften Softwaredesigns. Solche Probleme werden oft durch die Nutzung undokumentierter Funktionsaufrufe seitens der Anwendungsentwickler oder unspezifizierte Änderung des Verhaltens einer DLL seitens der Bibliotheksentwickler ausgelöst.
Bei heutigen Windows-Betriebssystemen wird dieser Nachteil vermieden, indem solche Systemdateien nicht an zentraler Stelle, sondern im jeweiligen Programmverzeichnis abgelegt werden. Diese Redundanz führt nicht nur zur Belegung zusätzlicher Festplattenkapazität, sondern kann auch zu Einbußen bei der Rechenleistung eines Systems führen. Aufgrund der inzwischen enorm gestiegenen Festplattenkapazitäten und durch den Einsatz von SSD sind diese Nachteile jedoch in den Hintergrund gerückt.

## Methoden zur Vermeidung

Es gibt erprobte Methoden, wie sich diese DLL-Konflikte vermeiden lassen. Diese Empfehlungen können jedoch nur wirksam sein, wenn sie in ihrer Gesamtheit umgesetzt werden.
* Es ist prinzipiell abzuwägen, ob in einem speziellen Anwendungsfall die potentiellen Nachteile einer DLL überhaupt durch die Vorteile überwogen werden. Wenn eine DLL das Ziel, modular von vielen Programmen gleichzeitig verwendet werden zu können, nicht erreicht, ist es besser, wenn ihre Funktion direkt vom Programm übernommen wird.
* Wenn Softwareentwickler Änderungen an einer DLL vornehmen müssen und sich die ursprüngliche Bibliothek nicht in die neue einbinden lässt, können sie den Programmcode direkt in ihr Programm einbauen (die Bibliothek wird statisch gelinkt).
* Lokal gespeicherte DLL-Versionen für ein bestimmtes Programm, genannt Private DLLs. Unter Windows haben diese DLL-Versionen, die im Programmordner der Anwendung abgelegt sind, eine höhere Priorität als die systemweit verfügbaren DLLs.
* Microsoft .NET erlaubt Programmen, eigene DLLs wahlweise im Programmverzeichnis abzulegen oder sie im Global Assembly Cache (GAC) zentral zu speichern, wobei der GAC jedem installierten Programm die von ihm geforderte Version der DLL zur Verfügung stellen kann.
* Angabe einer Versionsbezeichnung im DLL-Dateinamen (z. B. atl80.dll, atl90.dll), um unterschiedliche Versionen gemeinsam installieren zu können.
* Installationsprogramme oder Paketmanager können DLL-Abhängigkeiten von Programmen verfolgen.
* Bibliotheken vom Betriebssystem zentral verwaltet lassen. Eine solche zentrale Verwaltung kann zum Beispiel die Kompatibilität alter Bibliotheksversionen zu neuen überprüfen und, sollte eine solche Versionsverträglichkeit nicht vorhanden sein, diese über den Einbau einer Schnittstelle in die Bibliothek wieder gewährleisten.

## DLL-Konflikte als Herausforderung für .NET

2001 veröffentlichte Microsoft die .NET-Programmierumgebung, die ein eigenes Paketverwaltungssystem, die sogenannten Assemblies, enthält. Diese Umgebung stellt vielverwendete Funktionen in einer Bibliothek bereit. Es wird vor allem Programmcode aus mehreren DLLs in einer Klasse zusammengefasst.
In .NET kann jedes Programm eigene Bibliotheken verwenden und diese im Stammverzeichnis des Programms ablegen. Alternativ können Assemblies aber auch zentral im Global Assembly Cache (GAC) abgelegt werden. Dieser ist jedoch im Gegensatz zu früheren Windows-Systemen in der Lage, mehrere Versionen einer Assembly zu verwalten (Side-by-side Assembly, WinSxS), so dass jedes laufende Programm die Version der DLL, mit der es verknüpft ist, zugewiesen bekommt.
Die Idee, verschiedene Versionen einer Datei zu verwalten, wird teilweise als Überrest veralteter Programmiertechniken begriffen. Es kann beispielsweise nicht ausgeschlossen werden, dass veraltete Programmversionen mit öffentlich bekannten Sicherheitslücken weiterhin ausgeführt werden, auch wenn eine neuere, abgesicherte Version installiert wird.

## Quellen

* 1 2 Rick Anderson: The End of DLL Hell. microsoft.com, 11. Januar 2000, archiviert vom Original am 5. Juni 2001; abgerufen am 7. Juli 2010 (englisch): „Private DLLs are DLLs that are installed with a specific application and used only by that application.“
* ↑ James Donald: Improved Portability of Shared Libraries. (pdf) Princeton University, 25. Januar 2003, archiviert vom Original am 26. September 2007; abgerufen am 29. August 2012 (englisch).
* ↑ Tim Pfeiffer: Windows DLLs: Threat or Menace? Dr. Dobb’s Journal, 1. Juni 1998, archiviert vom Original am 7. August 2010; abgerufen am 7. Juli 2010.
* ↑ Arnaud Desitter: Using static and shared libraries across platforms; Row 9: Library Path. ArnaudRecipes, 20. Juli 2011, archiviert vom Original am 20. Juli 2011; abgerufen am 26. Januar 2012 (englisch): „win32 runtime library path: . and then PATH“