new/delete zwecks Speicherlecks loggen



  • Hallo!

    Um Speicherlecks in einer embedded Anwendung zu finden, hab ich new und delete neu definiert. (natürlich auch die array-Varianten)

    Nun logge ich bei new folgendes mit:
    * wieviel Speicher wird angefragt
    * Beginnadresse
    * File und Line des Aufrufers von new

    Bei delete logge ich folgendes mit:
    * Beginnadresse

    struct LogEntry
    {
    const char* fileName;
    int lineNr;
    void* memPtr;
    size_t size;
    char id; // gibt an ob new, delete, new[] oder delete[] aufgerufen wurden
    }

    LogEntry logBuf[LOG_LEN];

    Die Infos landen in einem Eintrag in Form einer struct mit den entsprechenden Members, und kommt dann in einen Einträge-Buffer der Länge 1000. Wenn der Buffer voll ist, schreibe ich alles in eine Datei (bzw. hänge es hinten an), und verwende den Buffer für die nächsten 1000 Einträge.
    Die Performance ist einigermaßen ok (könnte besser sein), aber dafür bekomme ich riesige Datenmengen. Da tut sich Excel damit schwer. In Excel vergleiche ich, ob es zu jeder Adresse und damit jedem new auch ein delete gibt.

    Andere Möglichkeit wäre es, die Einträge in einen viel viel größeren Buffern zu speichern, und die entsprechenden new Einträge bei einem delete sofort aus dem Buffern zu löschen. Erst ganz am Ende des Programms speichere ich alles in eine Datei (also alle gültigen Einträge auf einmal).
    Problem: Ich hatte mit diesem Ansatz richtig schlechte Performance, denn jedes delete muss seinen Gegenpart, den new Eintrag finden und löschen. Und jedes new muss erstmal einen freien Platz in der Liste finden.
    Um alle Einträge reinzubekommen, brauche ich aber eine Liste mit einigen 10.000 Einträgen. Da wird die lineare Suche (da unsortierte Liste) ziemlich zäh. (wie schon gesagt - embedded - nicht gerade flott)

    Nun zu meinen 2 Fragen:

    Gibt es andere Vorschläge, um über die new/delete Aufrufe Buch zu führen?
    Letztlich wünsche ich mir eine Datei, mit der ich rausfinden kann, welche Speicherbereiche nicht gelöscht werden.

    Weitere Frage: Würde gerne vor und nach jedem Speicherbereich beim new Aufruf noch einen Marker (Bitmuster) setzen, sodass ich beim delete prüfen kann, ob über den Speicherbereich hinaus geschrieben wurde. Nun macht mir das Alignment etwas Sorgen. Wenn ich vorne und hinten 8byte anhänge, so sollte es mit dem Alignment keine Probleme geben, oder? (double muss ja auf manchen Architekturen 8byte ausgerichtet sein)
    100byte bei new angefordert führen also zu 116byte:
    .....[8byte für Bitmuster][100byte Nutzdaten][8byte für Bitmuster].....



    1. In modernem C++ braucht man kein new/delete.
    2. Dafür gibt es schon Tools, suche mal nach Profiler. Ich nutze valgrind, aber VS kann das sicher auch.
    3. Kann man theoretisch so machen wie du gedacht hast, ist aber nicht ganz einfach.




  • @xpp & Christian: Embedded ...

    New/Delete auf deine Weise ist Okay.

    Wenn ich vorne und hinten 8byte anhänge,

    Warum vorn und hinten? Iterierst du rueckwaerts, eher ungewoehnlich?

    Letztendlich produziert das Loggen von new/delete fuer eine ganze Anwendung zuviele Daten. Auch wird new/delete wahrscheinlich von jedem std::vector auch mitgeloggt. Da schlage ich Modultests vor, um nicht ganz soviel Daten zu produzieren.



  • knivil schrieb:

    @xpp & Christian: Embedded ...

    New/Delete auf deine Weise ist Okay.

    Wenn ich vorne und hinten 8byte anhänge,

    Warum vorn und hinten? Iterierst du rueckwaerts, eher ungewoehnlich?

    Letztendlich produziert das Loggen von new/delete fuer eine ganze Anwendung zuviele Daten. Auch wird new/delete wahrscheinlich von jedem std::vector auch mitgeloggt. Da schlage ich Modultests vor, um nicht ganz soviel Daten zu produzieren.

    1. guter Vorschlag, ich aktiviere das Logging einfach immer nur für überschaubar große Untereinheiten des Programms. Vor allem eine einfache Lösung!

    2. theoretisch kann man natürlich auch nach vorne über die Grenzen schreiben, aber hast schon Recht, der andere Fall ist sicher der häufigere.


Anmelden zum Antworten