Hallo,
On 07.02.2012 23:34, Roman Racine wrote:
> Ich habe hier Binaries einer Closed Source Software. Diese hat ein Memory
> Leak, das unter gewissen Anwendungsmustern, die in letzter Zeit gehäuft
> vorkommen, extrem störend ist, d.h. ständige Neustarts notwendig macht.
>
> Ich habe mir gedacht, dass dieses Problem behoben werden könnte, wenn
> Aufrufe für malloc() u.ä. von der glibc in eine Library umgebogen würde, die
> Garbage Collection macht. Dadurch hätte man diese Funktionalität, ohne dass
> die Software neu compiliert werden müsste (was im Moment nicht möglich ist,
> da der Source Code nicht verfügbar ist).
das kannst Du guten Gewissens vergessen.
Zwar ist es technisch möglich, die malloc/calloc/realloc/free-Aufrufe
umzuleiten falls, und nur falls die Anwendung durchgängig eine
DLL-Version der C-Runtime verwendet. Die Vorgehensweise ist im Prinzip
per DLL-Rename alle Referenzen der Anwendung auf die Runtime-DLL auf
eine eigene DLL umzubiegen. Das kann man binär im Executable patchen.
Die eigene DLL leitet dann alle Runtime-Aufrufe auf die Original-DLL um
und ersetzt nur einige Aufrufe. Wenn man es richtig macht, hält sich der
Overhead bis hier hin in Grenzen, denn bis auf die ersetzten Aufrufe
kann man die Umleitung statisch vom Executable-Loader durchführen
lassen, so dass zur Laufzeit wie bisher die Original-Runtime
angesprungen wird. Aber ...
> Ein ähnliches Vorgehen hat valgrind zur detektierung von Memory Leaks,
> technisch möglich müsste es also sein, allerdings habe ich nichts
> dergleichen gefunden. Der Boehm Garbage Collector erfordert anscheinend,
> dass die Software neu compiliert wird.
... der Knackpunkt ist, dass die ersetzten Runtime-Funktionen keine
Möglichkeit haben, herauszufinden, welche Speicherblöcke tatsächlich
noch benötigt werden. Dazu müsste man das Programm komplett auseinander
nehmen. Das ist letztlich auch der Ansatz von valgrind, allerdings
funktioniert er nicht fehlerfrei. Und außerdem ist das Programm damit
nicht mehr produktiv nutzbar.
Programmfehler bleiben Programmfehler. Wenn die Anwendung leckt, hat man
eigentlich nur wenige Möglichkeiten.
- Man kann solange mehr Speicher einbauen, bis es nicht mehr so sehr stört.
- Man kann die Anwendung regelmäßig (automatisch) neu starten.
- Wenn die Leckage-Blöcke größer als die System-Page-Size (typ. 4k)
sind, kann man einfach großen Swap-Space bereitstellen, und dem
Betriebssystem den Rest überlassen. Das führt allerdings zu einer
Fragmentierung der Memory-Descriptoren und mithin zu mehr oder minder
deutlichen Performance-Verlusten.
Marcel