malloc-Tool debuggen
Das Debugging von Anwendungen, die den vom Subsystem malloc zugeordneten Speicher nicht verwalten, kann schwierig und mühsam sein. Dies liegt daran, dass es im Allgemeinen keine Synchronizität zwischen dem Einfügen eines Fehlers und der Exposition des resultierenden Symptoms gibt.
Hinzu kommt die inhärente Komplexität der Speicherzuordnung, bei der Tausende von Zuordnungen asynchron und gleichzeitig vorgenommen, rückgängig gemacht und (vielleicht) aufgerufen werden, und zwar in einem Multithread-Kontext, der eine robuste und effiziente Synchronisation erfordert.
Aus diesen Gründen liegt der Fokus unserer Debugging-Tools in erster Linie darauf, die Zeit der Symptomerkennung näher an die Zeit der Fehlereinfügung zu bringen. Dies hilft dem Anwendungsentwickler, genauer zu bestimmen, welcher Codeabschnitt für das Festschreiben des Fehlers verantwortlich ist.
Es wurden viele verschiedene Debugging-Tools für malloc entwickelt. Einige können in Kombination mit anderen Debugging-Tools und mit allen Zuordnungsrichtlinien verwendet werden; andere sind eingeschränkter in ihrer Verwendung. Viele der Debugging-Tools verbrauchen zusätzlich zu den für den Prozess erforderlichen Ressourcen. Es ist Aufgabe des Anwendungsentwicklers, bei Bedarf ausreichende Ressourcen bereitzustellen.
Leistungsaspekte
Die Debug-malloc-Tools sind für die Verwendung in Vollzeit, konstant oder systemweit nicht geeignet. Obwohl sie für einen minimalen Leistungseinfluss auf die Anwendung, für die das Debugging ausgeführt wird, konzipiert sind, können erhebliche negative Auswirkungen auf den Gesamtsystemdurchsatz auftreten, wenn sie weit verbreitet in einem System eingesetzt werden. Insbesondere wird die Einstellung MALLOCDEBUG=catch_overflow in der Datei /etc/environment nicht empfohlen und führt wahrscheinlich zu erheblichen Systemproblemen, wie z. B. einer übermäßigen Belegung des Paging-Bereichs. Die Tools debug malloc sollten nur verwendet werden, um einzelne Anwendungen oder kleine Gruppen von Anwendungen gleichzeitig zu debuggen.
Aufgrund der zusätzlichen Arbeit, die mit der Durchführung verschiedener Laufzeitprüfungen verbunden ist, wird die Leistung des malloc -Subsystems mit aktivierten Debug-malloc-Tools (je nachdem, welches Tool verwendet wird) variabel beeinträchtigt, aber nicht so, dass Anwendungen unbrauchbar werden. Nachdem das Problem behoben wurde, sollten die Debug-malloc-Tools inaktiviert werden, um die malloc -Subsystemleistung wiederherzustellen.
Hinweise zu Platten und Speicher
Wenn die catch_overflow -oder Malloc-Protokolltools aktiviert sind, verbraucht das Subsystem malloc erheblich mehr Speicher.
Für catch_overflowwird jede malloc-Anforderung um das 4096 + 2-fache der Größe von 'unsigned long' erhöht und dann auf das nächste Vielfache des Makros PAGESIZE aufgerundet. catch_overflow kann sich als zu speicherintensiv erweisen, um für sehr große Anwendungen verwendet zu werden, aber für die meisten Anwendungen, die Speicherdebugging benötigen, sollte die zusätzliche Speicherverwendung kein Problem verursachen. Bei großen Anwendungen kann die Verwendung der Optionen debug_range und functionset auf catch_overflow die Speicherbelegung erheblich verringern, sodass das Programm stückweise getestet werden kann.
Für Malloc Log wird ein Zuordnungsdatensatz für jede aktive Zuordnung im Prozess gespeichert. Dieser Speicheraufwand kann minimiert werden, indem eine geringe Anzahl gespeicherter Stackzeiger angegeben wird.
Wenn die Anwendung, für die das Debugging ausgeführt wird, häufig malloc -Subsystemzuordnungsroutinen aufruft, können Probleme mit der Speicherbelegung auftreten, wenn die Debugging-malloc-Tools aktiviert sind, die verhindern könnten, dass die Anwendung in einem einzelnen Segment ordnungsgemäß ausgeführt wird. In diesem Fall kann es hilfreich sein, die Anwendung für den Zugriff auf zusätzlichen Speicher zu aktivieren, indem der Befehl ulimit und die Option -bmaxdata des Befehls ld verwendet werden.
ulimit -d unlimited
ulimit -s unlimited Um maximal 8 Segmente für einen 32-Bit-Prozess zu reservieren, muss die Option -bmaxdata als -bmaxdata:0x80000000angegeben werden.
Wenn die Debugging-malloc-Tools inaktiviert sind, können die Standardwerte für ulimit und -bmaxdata wiederhergestellt werden.
Weitere Informationen zum Befehl ulimit und zur Option -bmaxdata finden Sie unter Large Program Support.
Die Debug-malloc-Tools sind für die Verwendung in einigen Debugsituationen nicht geeignet. Da einige der Debug-malloc-Tools den Systemaufwand für eine Seite oder mehr pro Zuordnung erfordern, wird die Speicherbelegung von Programmen, die viele kleine Zuordnungsanforderungen ausgeben, drastisch erhöht. Bei diesen Programmen treten möglicherweise neue Fehler auf, da Speicherzuordnungsanforderungen aufgrund eines Mangels an Speicher oder Paging-Bereich verweigert werden. Diese Fehler sind nicht unbedingt Fehler in dem Programm, für das das Debugging durchgeführt wird, und sie sind keine Fehler im Tool 'debug malloc'.
- Starten Sie den X-Server mit inaktiviertem catch_overflow.
- Starten Sie ein Terminalfenster (z. B. dtterm, xterm, aixterm).
- Setzen Sie die entsprechenden Umgebungsvariablen in der Terminalfenstersitzung, um catch_overflow zu aktivieren.
- Rufen Sie das zu debuggende X Client-Programm innerhalb desselben Fensters auf.
Debug für malloc aktivieren
Debug Malloc ist nicht standardmäßig aktiviert, aber aktiviert und konfiguriert, indem die Umgebungsvariable MALLOCDEBUG auf die entsprechende Option gesetzt wird. Wenn mehrere Optionen erforderlich sind, können diese durch Kommas (,) voneinander getrennt werden. Die im Tandem angeforderten Optionen müssen miteinander kompatibel sein.
Malloc-Debugging-Tools
Pufferüberlauferkennung
Speicherverwaltungsfehler werden manchmal dadurch verursacht, dass das Anwendungsprogramm über das Ende eines zugeordneten Puffers hinaus schreibt. Da dies oft keine unmittelbare Konsequenz hat, treten Symptome erst viel später auf, wenn der überschriebene Speicher (der normalerweise zu einer anderen Zuordnung gehört) referenziert wird und die darin ursprünglich gespeicherten Daten nicht mehr enthält.
Mit der Debugoption catch_overflow können Benutzer Speicherüberschreibungen, Überschreibungen, doppelte Freimengen und die Wiederverwendung von freigegebenem Speicher, der von der Subroutine malloc zugeordnet wurde, ermitteln. Speicherprobleme, die vom Tool 'catch_overflow' erkannt werden, führen zu einem Abbruchaufruf oder einer Segmentierungsverletzung (SIGSEGV). Wenn ein Fehler erkannt wird, wird die Anwendung in den meisten Fällen sofort gestoppt und eine Kerndatei erzeugt.
catch_overflow wirkt sich auf die Zuordnungen der folgenden Zuordnungsrichtlinien und Optionen aus:- Standardzuordnungsrichtlinie
- Watson -Zuordnungsrichtlinie
- Option Malloc Multiheap
- Option Malloc Threadcache
- Option 'malloc Disclaim'
Die Debugoption catch_overflow wird durch Festlegen von MALLOCDEBUG=catch_overflowaktiviert. Dadurch wird die Identifikation von Speicherüberschreibungen und -überschreibungen aktiviert.
- ausrichten
Standardmäßig gibt die Subroutine malloc einen Zeiger zurück, der an einer 2-Wort-Grenze ausgerichtet ist. Dies ist notwendig für die Einhaltung von Standards und für Programme, die keine unabgestimmten Speicherzugriffe akzeptieren (z.B. Programme, die DCE-Komponenten verwenden). Aufgrund einer Anfrage in der Implementierung der Option
catch_overflowist es jedoch möglich, dass ein Programm einen Puffer um einen Betrag überschreibt, der kleiner ist als der Ausrichtungswert, ohne voncatch_overflowerkannt zu werden. Die Optionalignkann verwendet werden, um das malloc -Subsystem anzuweisen, diese Standardausrichtung zu ignorieren, um die Anzahl der Bytes zu verringern oder zu eliminieren, durch die ein Puffer ohne Erkennung überschrieben werden kann. Eine benutzerdefinierte Ausrichtung kann für jede Potenz von zwei zwischen 0 und 4096 einschließlich angegeben werden (z. B. 0,1,2,4, ...). Die Werte 0 und 1 werden als identisch behandelt, d. h., es erfolgt keine Speicherausrichtung. Daher führen Speicherzugriffe, die über den zugeordneten Bereich hinausgehen, zu einem SEGFAULT.Die Optionalignist Teil der Optioncatch_overflowund nur von Bedeutung, wenncatch_overflowaktiviert ist. Um eine vom Standard abweichende Ausrichtung zu aktivieren, legen Sie die Umgebungsvariable MALLOCDEBUG wie folgt fest:
Dabei ist n die gewünschte Ausrichtung.MALLOCDEBUG=catch_overflow,align:nVerwenden Sie die folgende Formel, um zu berechnen, wie viele Byte von Overreads oder Überschreibungen die Optioncatch_overflowfür eine bestimmte Zuordnungsanforderung zulässt, wenn n die angeforderte Ausrichtung und Größe die Anzahl der zuzuordnenden Byte ist:((((size / n) + 1) * n) - size) % nDas folgende Beispiel veranschaulicht die Auswirkung der Option align auf die Fähigkeit der Anwendung, Überleseoperationen oder Überschreibungen mit aktivierter Option catch_overflow auszuführen. In diesem Beispiel wird die Option align mit dem Wert 2 angegeben:MALLOCDEBUG=align:2,catch_overflowDie Optioncatch_overflowbehandelt Overreads und Overwrites wie folgt:- Wenn eine gerade Anzahl von Bytes zugeordnet wird, ordnet malloc genau die Anzahl der angeforderten Bytes zu, was 0 Bytes von Overreads oder Overwrites zulässt.
- Wenn eine ungerade Anzahl von Byte zugeordnet wird, ordnet malloc die Anzahl der angeforderten Byte plus ein zusätzliches Byte zu, um die erforderliche Ausrichtung zu erfüllen. Dies ermöglicht 1 Byte möglicher Überschreibungs-oder Überschreibungen.
- override_signal_handling (Signalverarbeitung überschreiben)
- Die Option
catch_overflowmeldet Fehler auf eine der folgenden Arten:- Speicherzugriffsfehler (z. B. der Versuch, über das Ende des zugeordneten Speichers hinaus zu lesen oder zu schreiben) führen zu einem Segmentierungsverstoß (SIGSEGV), der zu einem Kernspeicherauszug führt.
- For other types of errors (such as trying to free space that was already freed), the
catch_overflowoption will output an error message, then call the abort function , which will send a SIGIOT signal to end the current process.
Wenn das aufrufende Programm die SIGSEGV-und SIGIOT-Signale blockiert oder abfängt, wird verhindert, dass die Option
catch_overflowFehler meldet. Die Optionoverride_signal_handlingbietet die Möglichkeit, diese Situation zu umgehen, ohne die Anwendung neu zu codieren und neu zu erstellen.Wenn die Optionoverride_signal_handlingangegeben ist, führt die Optioncatch_overflowbei jedem Aufruf einer malloc -Subsystemroutine die folgenden Aktionen aus:- Inaktivieren Sie alle vorhandenen Signalhandler, die von der Anwendung für SIGSEGV oder SIGIOT eingerichtet wurden.
- Setzen Sie die Aktion für SIGIOT und SIGSEGV auf den Standardwert (SIG_DFL).
- Entsperren Sie sowohl SIGIOT als auch SIGSEGV.
Wenn ein Anwendungssignalhandler die Aktion für SIGSEGV zwischen Speicherzuordnungsroutinenaufrufen ändert und dann einen ungültigen Speicherzugriff versucht, kann die Option catch_overflow den Fehler nicht melden (die Anwendung wird nicht beendet und es wird keine Kerndatei erstellt).
Hinweis:- Die Option
override_signal_handlingkann in einer Threadanwendungsumgebung unwirksam sein, da die Optioncatch_overflowdie Subroutine sigprocmask verwendet und viele Threadprozesse die Subroutine pthread_sigmask verwenden. - Wenn ein Thread die Subroutine sigwait aufruft, ohne SIGSEGV und SIGIOT in die Signalgruppe einzuschließen, und die Option
catch_overflowanschließend einen Fehler erkennt, wird der Thread blockiert, da die Optioncatch_overflownur SIGSEGV oder SIGIOT generieren kann. - Wenn ein Zeiger auf ungültigen Speicher an eine Kernelroutine übergeben wird, schlägt die Kernelroutine fehl und gibt in der Regel mit der Fehlernummer EFAULT zurück. Wenn die Anwendung die Rückgabe des Systemaufrufs nicht überprüft, wird dieser Fehler möglicherweise nicht erkannt.
- Debugbereich
Wenn die Option
catch_overflowaktiviert ist, wird die Pufferüberlauferkennung standardmäßig für jede Zuordnung im Programm ausgeführt. Wenn die Optiondebug_rangeangegeben wird, werden nur Zuordnungsanforderungen, die zwischen einer benutzerdefinierten minimalen und maximalen Größe liegen, durch die Optioncatch_overflowPufferüberläufe erkannt. Andernfalls wird keine Pufferüberlauferkennung ausgeführt. Diese Option ermöglicht es dem Benutzer, die Menge an zusätzlichen Speicherressourcen zu steuern, die von der Optioncatch_overflowverbraucht werden, indem das Tool in bestimmten Fällen verwendet wird.Die Optiondebug_rangeist nur im Kontext der Optioncatch_overflowaussagekräftig. Sie wird wie folgt aktiviert:
Dabei ist min die Untergrenze und max die Obergrenze des Bereichs, in dem die Pufferüberlauferkennung ausgeführt werden soll. Wenn 0 als Mindestwert angegeben wird, wird für alle Elemente, die kleiner als der Maximalwert sind, eine Pufferüberlauferkennung ausgeführt. Wenn 0 als Maximalwert angegeben wird, wird für alle Elemente, die größer als der Mindestwert sind, eine Pufferüberlauferkennung durchgeführt.MALLOCDEBUG=catch_overflow,debug_range:min:maxEinschränkung:Aufgrund einer internen Implementierungsanforderung muss jede Zuordnung immer noch mindestens eine Seitengröße aufweisen. Daher reduziert die Option
debug_rangelediglich den Systemaufwand für die Optioncatch_overflow, anstatt sie zu entfernen.Wenn die Subroutine realloc mit einer Zuordnungsanforderung aufgerufen wird, die in den benutzerdefinierten Bereich fällt, wird die Pufferüberlauferkennung auch dann ausgeführt, wenn die ursprüngliche Zuordnung nicht innerhalb des angegebenen Bereichs lag. Das Gegenteil ist auch der Fall.
Anmerkung: Wenn die Optionoverride_signalzusammen mit der Optiondebug_rangefestgelegt wird, wird das Überschreiben des Signalverhaltens SIGIOT und SIGSEGV für alle Zuordnungen ausgeführt.- Funktionsset
Aufgrund einer internen Implementierungsanforderung muss jede Zuordnung immer noch mindestens eine Seitengröße haben. Daher reduziert die Option
functionsetlediglich den Systemaufwand für die Optioncatch_overflow, anstatt sie zu entfernen.Wenn die Subroutine realloc von einer Funktion aufgerufen wird, die Mitglied der benutzerdefinierten Funktionsliste ist, wird die Pufferüberlauferkennung auch dann ausgeführt, wenn die ursprüngliche Zuordnung nicht von einer angegebenen Funktion vorgenommen wurde. Das Gegenteil ist auch der Fall.
Anmerkung: Wenn die Optionoverride_signalzusammen mit der Optionfunctionsetfestgelegt wird, wird das Überschreiben des Signalverhaltens SIGIOT und SIGSEGV für alle Zuordnungen ausgeführt.Die Option
functionsetüberprüft nicht die Gültigkeit der in der Liste angegebenen Funktionen.- 'allow_overreading'
Wenn die Debugoption
catch_overflowaktiviert ist und das aufrufende Programm versucht, über das Ende des zugeordneten Speichers hinaus zu lesen, tritt standardmäßig eine Segmentierungsverletzung auf und der Prozess erstellt einen Kernspeicherauszug. Der Benutzer ist jedoch möglicherweise nicht daran interessiert, diesen Fehlertyp abzufangen, und hat möglicherweisecatch_overflowaktiviert, um gefährlichere Überschreibungen abzufangen. Wenn Sie die Optionallow_overreadingangeben, ignoriert die Optioncatch_overflowÜberlesevorgänge, sodass andere Fehlertypen, die als schwerwiegender betrachtet werden können, zuerst erkannt werden können.Die Optionallow_overreadingist nur im Kontext der Optioncatch_overflowaussagekräftig. Sie wird wie folgt aktiviert:MALLOCDEBUG=catch_overflow,allow_overreading,- 'postfree_checking'
Die Option
postfree_checkingverbraucht eine beträchtliche Menge an zusätzlichem Speicher. Programme mit sehr großem Speicherbedarf können die Optionpostfree_checkingmöglicherweise nicht verwenden.- Malloc-Trace
Malloc Trace ist eine Debugoption, die das Tracing aller Aufrufe an die malloc -Subsystem-API über die Systemtracefunktion ermöglicht.
- Mallow-Protokoll
Malloc Log ist eine Debugoption, die dem Benutzer eine Laufzeitdatenbank aktiver Zuordnungen im malloc -Subsystem bereitstellt.
- Berichtszuordnungen
Die Option
report_allocationsist ein Tool zum Erkennen von Speicherlecks in einem Anwendungsprogramm. Die Optionreport_allocationsverwendet die von Malloc Log erstellte Datenbank, um eine Liste der momentan vom Benutzer gehaltenen Zuordnungen zu melden. Jede erfolgreiche Zuordnung wird zum Zeitpunkt der Anforderung durch das Malloc-Protokoll aufgezeichnet. Wenn eine Zuordnung aufgehoben wird, entfernt Malloc Log den zugehörigen Datensatz aus der Datenbank. Beim Prozessexit wird die Liste der noch aktiven Zuordnungen in der Standardfehlerausgabe (stderr) ausgegeben, die eine Liste der Zuordnungen enthält, die nie von ihren aufrufenden Programmen freigegeben wurden.Für die Optionreport_allocationsist die Funktionalität von Malloc Log erforderlich. Daher wird das Malloc-Protokoll implizit aktiviert, wennreport_allocationsaktiviert ist. Die Optionreport_allocationsist wie folgt aktiviert:MALLOCDEBUG=report_allocations- validate_ptrs
Standardmäßig validieren die malloc -Subsystem-APIs ihre Eingabezeiger nicht, um sicherzustellen, dass sie tatsächlich zuvor zugeordneten Speicher referenzieren. Wenn einer dieser Zeiger ungültig ist, kann es zu einer schwerwiegenden Beschädigung des Heapspeichers kommen. Die Angabe der Option
validate_ptrsbewirkt, dass die malloc -Subsystem-APIs eine umfassende Validierung ihrer Eingabezeiger durchführen. Wenn ein Zeiger als ungültig erkannt wird (d. h., er verweist nicht auf Speicher, der zuvor durch einen Aufruf der Subsystem-API malloc zugeordnet wurde), wird eine Fehlernachricht ausgegeben, die angibt, warum er ungültig ist, die Abbruchfunktion aufgerufen und eine Kerndatei erstellt. Die Optionvalidate_ptrsähnelt der Unteroptionverbose. Die Optionvalidate_ptrswird nicht wirksam, wenn die Optionpostfree_checkingaktiviert ist.Die Optionvalidate_ptrsist wie folgt aktiviert:MALLOCDEBUG=validate_ptrs- Malloc-Erkennung
Malloc Detect ist eine Debugoption zum Erkennen und Melden von Beschädigungen der Datenstrukturen des internen malloc -Subsystems bei jedem Aufruf einer malloc -Subsystem-API.
- verbose
Unteroption von Malloc Detect
- Checkarena
Unteroption von Malloc Detect
- output
Standardmäßig senden die malloc-Debugoptionen ihre Ausgabe an stderr. Dies ist möglicherweise nicht für alle Programme erwünscht. Mit der Option
outputkönnen Sie ein alternatives Ziel für gedruckte Informationen angeben. Die Ausgabe kann entweder an stderr, stdout oder an eine beliebige Datei auf dem System gesendet werden.Die Optionoutputist wie folgt aktiviert:MALLOCDEBUG=output:<filename>- continue
Viele malloc-Debugging-Optionen rufen abort () auf, wenn sie einen Fehler feststellen. Dies ist nicht immer das gewünschte Verhalten für alle Programme. Die Option
continueist vorhanden, um das Subsystem malloc anzuweisen, nach der Erkennung eines synchronen Fehlers fortzufahren, anstatt den Prozess abzubrechen. Fehlernachrichten werden weiterhin in den entsprechenden Kanälen protokolliert.Die Optioncontinueist wie folgt aktiviert:MALLOCDEBUG=continue- Malloc-Debug-Füllung
Malloc debug fill ist eine Debugoption, mit der der Speicher, der über die malloc () -Aufrufe zugeordnet wurde, mit einem benutzerdefinierten Muster für Debugzwecke gefüllt wird.
Das Muster sollte als Zeichenfolge angegeben werden (Beispiel: export MALLOCDEBUG=fill: "abc" legt den über malloc zugeordneten Speicher mit dem Muster "abc" fest). Es sind maximal 128 Zeichen zulässig. Wenn das Muster nicht angegeben wird, wird die Fülloption ignoriert.
Die Option malloc debug fill kann wie folgt aktiviert werden:
MALLOCDEBUG=fill:patternDas Muster kann eine Oktal-oder Hexadezimalzahl sein, die in Form einer Zeichenfolge angegeben wird. d. h., das Muster "\101" wird als Oktalschreibweise für Zeichen 'A' und das Muster “\x41”als Hexadezimalschreibweise für Zeichen 'A' behandelt.
Wenn eine ungültige Oktalzahl angegeben wird, z. B. \777, die nicht in 1 Byte enthalten sein kann, wird als \377 der maximale Oktalwert gespeichert, der als 1 Byte gespeichert werden kann.