Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-8362-1411-7
Pfeil 27 Sicheres Programmieren
Pfeil 27.1 Buffer-Overflow (Speicherüberlauf)
Pfeil 27.1.1 Speicherverwaltung von Programmen
Pfeil 27.1.2 Der Stack-Frame
Pfeil 27.1.3 Rücksprungadresse manipulieren
Pfeil 27.1.4 Gegenmaßnahmen zum Buffer-Overflow während der Programmerstellung
Pfeil 27.1.5 Gegenmaßnahmen zum Buffer-Overflow, wenn das Programm fertig ist
Pfeil 27.1.6 Programme und Tools zum Buffer-Overflow
Pfeil 27.1.7 Ausblick
Pfeil 27.2 Memory Leaks (Speicherlecks)
Pfeil 27.2.1 Bibliotheken und Tools zu Memory Leaks
Pfeil 27.3 Tipps zu Sicherheitsproblemen


Rheinwerk Computing - Zum Seitenanfang

27.2 Memory Leaks (Speicherlecks) Zur nächsten ÜberschriftZur vorigen Überschrift

Wie bei Buffer Overflows sind auch Memory Leaks in den meisten Fällen durch Programmierfehler zu erklären. Der erste Verdacht, es könnte sich bei Memory Leaks um Hardwareprobleme handeln, täuscht.

Ein Memory Leak entsteht, wenn ein Programm dynamisch Speicher alloziert (malloc(), realloc(), ...) und diese Speicherressourcen nicht mehr an das System zurückgibt (mittels free()). Es steht nicht unendlich viel Speicher vom Heap dafür zur Verfügung.

Programme wie das jetzt folgende erzeugen keine Probleme, wenn der Speicher nicht mehr an den Heap zurückgegeben wird:

/* mleak1.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
   char *p;

   p = malloc(sizeof("Hallo Welt\n"));
   if(NULL == p) {
      fprintf(stderr, "Abbruch: Speichermangel !!\n");
      return EXIT_FAILURE;
   }
   strcpy(p, "Hallo Welt\n");
   printf("%s",p);
   return EXIT_SUCCESS;
}

Hier bekommt der Heap seinen Speicher bei Beendigung des Programms sofort wieder zurück.

Was ist aber mit Programmen, die dauerhaft im Einsatz sein müssen? Ein gutes Beispiel sind Telefongesellschaften, die jedes laufende, eingehende und ausgehende Gespräch nach dem FIFO-Prinzip auf dem Heap ablegen und ständig für diese Datensätze Speicher auf dem Heap allozieren bzw. für ältere Datensätze wieder freigeben müssen.

Ein (stupides) Beispiel:

/* mleak2.c */
#include <stdio.h>
#include <stdlib.h>

int main(void) {
   char *p;

   while(p = malloc(64000)) {
      if(NULL == p) {
         fprintf(stderr, "Speicherplatzmangel!!\n");
         return EXIT_FAILURE;
      }
      /* Tu was mit dem reservierten Speicher. */
   }
   return EXIT_SUCCESS;
}

Dieses Programm wird wohl eine Weile ohne Probleme laufen. Aber je länger das Programm läuft, umso mehr Speicher benötigt es vom Heap. Dies wird sich auf Dauer schlecht auf die Performance des Systems auswirken. Denn der Heap ist ja nicht nur für ein Programm allein da. Die anderen Programme, die ebenfalls Ressourcen benötigen, werden immer langsamer. Am Ende bleibt einem nichts anderes mehr übrig, als das System neu zu starten (abhängig vom Betriebssystem und der Art der Anwendung).

Meistens ist das Programm aber längst fertiggestellt, wenn ein Speicherleck gefunden wird. Dann kann guter Rat teuer werden, wenn Sie sich nicht auskennen.

Eine primitive Möglichkeit, sofern Sie im Besitz des Quellcodes sind, ist es, sogenannte Wrapper-Makros für speicherallozierte und speicherfreigebende Funktionen zu schreiben, beispielsweise für die malloc()-Funktion:

#define malloc(size) \
        malloc(size);\
        printf("malloc in Zeile %ld der Datei %s (%ld Bytes) \n"\
        ,__LINE__,__FILE__, size);\
        count_malloc++;

Bei Verwendung der malloc()-Funktion im Programm wird jetzt jeweils eine Ausgabe auf dem Bildschirm erzeugt, die anzeigt, in welcher Zeile und in welchem Programm die Funktion malloc() vorkommt und wie viel Speicher sie verwendet. Außerdem wird die Verwendung von malloc() mitgezählt.

Dasselbe wird anschließend auch mit der Funktion free() gemacht. Die Anzahl der gezählten malloc()- und free()-Aufrufe wird am Ende in eine Datei namens DEBUG_FILE geschrieben.

/* mem_check.h */
#ifndef MEM_CHECK_H
#define MEM_CHECK_H
#define DEBUG_FILE "Debug"

static int count_malloc=0;
static int count_free  =0;
FILE *f;

#define malloc(size) \
        malloc(size);\
        printf("malloc in Zeile %d der Datei %s (%d Bytes) \n"\
        ,__LINE__,__FILE__, size);\
        count_malloc++;

#define free(x)\
        free(x); \
        x=NULL;\
        printf("free in Zeile %d der Datei %s\n",
               __LINE__,__FILE__);\
        count_free++;

#define return EXIT_SUCCESS; \
        f=fopen(DEBUG_FILE, "w");\
        fprintf(f, "Anzahl malloc : %d\n",count_malloc);\
        fprintf(f, "Anzahl free   : %d\n",count_free);\
        fclose(f);\
        printf("Datei : %s erstellt\n", DEBUG_FILE);\
        return EXIT_SUCCESS;

#endif

Hier wurde eine Headerdatei namens mem_check.h erstellt, mit der alle Aufrufe von malloc() und free() auf dem Bildschirm ausgeben werden. Sie erfahren dadurch, in welcher Datei und welcher Zeile sich ein Aufruf dieser Funktion befindet. Außerdem wird auch die Anzahl der malloc()- und free()-Aufrufe mitgezählt. Sind mehr malloc()-Aufrufe als free()-Aufrufe vorhanden, wurde auf jeden Fall ein Speicherleck im Programm gefunden. Hier sehen Sie ein Listing zum Testen:

/* use_mem_check.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mem_check.h"

int main(void) {
   char *p;

   p = malloc(sizeof("Hallo Welt\n"));
   if(NULL == p) {
      fprintf(stderr, "Speichermangel!!!\n");
      return EXIT_FAILURE;
   }
   strcpy(p, "Hallo Welt\n");
   printf("%s",p);
   malloc(1024);
   free(p);
   return EXIT_SUCCESS;
}

In der Praxis und bei größeren Projekten ist diese Version, Memory Leaks aufzuspüren, nur bedingt geeignet. Mit dem Makro return 0 habe ich es mir allzu leicht gemacht. Dies setzt nämlich voraus, dass ein Programm auch damit beendet wird. Oft haben Sie es aber mit dauerhaft laufenden Programmen zu tun.

Genauso sieht es mit der Zuordnung des allozierten und freigegebenen Speichers aus. Welches malloc() gehört zu welchem free()? Aber das Prinzip dürfte Ihnen klar geworden sein. Wenn Sie Fehler wie Memory Leaks finden wollen, haben Sie notfalls mit Wrapper-Makros eine gute Möglichkeit.

Meistens werden Sie schon eher auf eines der mittlerweile vielen Tools oder auf eine der Bibliotheken zurückgreifen, die zur Erkennung von Memory Leaks programmiert wurden.


Rheinwerk Computing - Zum Seitenanfang

27.2.1 Bibliotheken und Tools zu Memory Leaks topZur vorigen Überschrift

Es gibt mittlerweile eine unüberschaubare Menge von solchen Debugging-Tools. Daher folgt hier ein kleiner Überblick mit Angabe der Bezugsquellen. Meistens finden Sie dabei auf diesen Webseiten gleich die Dokumentation für die Anwendung.

ccmalloc

Bezugsquelle: http://www.inf.ethz.ch/personal/biere/projects/ccmalloc/

ccmalloc wird mit dem C/C++-Programm verlinkt und gibt nach Beendigung des Programms einen Bericht über Memory Leaks aus. ccmalloc ist nicht geeignet, um festzustellen, ob versucht wurde, aus illegalen Speicherbereichen zu lesen.

dbmalloc

Bezugsquelle: ftp://ftp.digital.com/pub/usenet/comp.sources.misc/volume32/dbmalloc/

dbmalloc ist in einer kommerziellen und einer kostenlosen Version erhältlich. Besondere Merkmale von dbmalloc sind:

  • Funktionsfluss, Datei und Zeileninformationen werden mit angegeben.
  • Gibt Adressen zurück (hilfreich zusammen mit Debuggern).
  • Grenzbereichsüberprüfung
  • Ausgabe auf die Standard-Fehlerausgabe
  • Findet Memory Leaks.

Generell wird dbmalloc, wie die meisten anderen Memory-Leak-Tools zu einem Programm hinzugelinkt. Sie müssen also im Besitz des Quellcodes sein, um diesen neu zu übersetzen. Eine gute Anleitung in deutscher Sprache zu dieser Bibliothek finden Sie unter der URL http://www.c-handbuch.org/.

mpatrol

Bezugsquelle: http://www.cbmamiga.demon.co.uk/mpatrol/

mpatrol ist ein leistungsfähiges Tool zum Auffinden von Memory Leaks, das sich leider auf die Performance des Programms negativ auswirkt. Folgende Funktionsmerkmale stehen Ihnen dabei zur Verfügung:

  • Ein Abbild des Stacks wird bei einem Fehler angezeigt.
  • Datei- und Zeilen-Informationen werden mit ausgegeben.
  • Es ist kompatibel zu dmalloc, dbmalloc, insure und purify.
  • Es ist nicht unbedingt erforderlich, neu zu übersetzen, um seine Programme mit mpatrol zu testen.
  • mpatrol findet alle denkbaren Fehler auf dem Heap. Fehler auf dem Stack werden nicht gefunden.

Um ein Programm mit mpatrol zu testen, ist genau wie bei den meisten anderen Tools ein Überschreiben der speicheranfordernden und freigebenden Funktionsaufrufe notwendig. Bei mpatrol können Sie dies auf zwei Arten machen: Entweder Sie linken das Programm zu der statischen oder dynamischen Bibliothek oder Sie binden diese später durch einen Aufruf von

mpatrol --dynamc ./testprog -i file

dynamisch mit in das Programm ein. Die letzte Möglichkeit funktioniert allerdings nur, wenn das Programm schon dynamisch zur Standard-C-Bibliothek übersetzt wurde, und selbst dann nur auf einigen wenigen Systemen, die diesen Befehl unterstützen. Für eine deutsche Dokumentation sei auch hier wieder auf die Webseite http://www.c-handbuch.org/ verwiesen.

Es gibt außer diesen hier genannten Tools noch eine Reihe weiterer sehr guter Tools zum Auffinden von Memory Leaks. Einen guten Überblick können Sie sich auf der Seite http://www.cs.colorado.edu/~zorn/MallocDebug.html verschaffen.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: C/C++






 C/C++


Zum Katalog: Einstieg in C






 Einstieg in C


Zum Katalog: Schrödinger programmiert C++






 Schrödinger
 programmiert C++


Zum Katalog: C++ Handbuch






 C++ Handbuch


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Rheinwerk Computing]

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de