Kann jemand kurz erklären, wie Valgrind funktioniert? Ein Beispiel: Woher weiß es, wann Speicher zugewiesen und freigegeben wird?
Valgrind führt Ihre Anwendung grundsätzlich in einer "Sandbox" aus. Während der Ausführung in dieser Sandbox können eigene Anweisungen für das erweiterte Debuggen und Profiling eingefügt werden.
Aus dem Handbuch:
Ihr Programm wird dann auf einer synthetischen CPU ausgeführt, die vom Valgrind-Kern bereitgestellt wird. Wenn neuer Code zum ersten Mal ausgeführt wird, übergibt der Kern den Code an das ausgewählte Werkzeug. Das Tool fügt diesem einen eigenen Instrumentierungscode hinzu und gibt das Ergebnis an den Kern zurück, der die weitere Ausführung dieses instrumentierten Codes koordiniert.
Valgrind bietet also einen virtuellen Prozessor, der Ihre Anwendung ausführt. Bevor Ihre Bewerbungsanweisungen jedoch verarbeitet werden, werden sie an Tools (z. B. memcheck) übergeben. Diese Tools ähneln Plugins und können Ihre Anwendung ändern, bevor sie auf dem Prozessor ausgeführt wird.
Das Tolle an diesem Ansatz ist, dass Sie Ihr Programm überhaupt nicht ändern oder neu verknüpfen müssen, um es in valgrind auszuführen. Dies führt dazu, dass Ihr Programm langsamer ausgeführt wird. Valgrind ist jedoch nicht dazu gedacht, die Leistung zu messen oder während der normalen Ausführung Ihrer Anwendung auszuführen. Dies ist also kein wirkliches Problem.
Valgrind ist ein DPA-Tool (Dynamic Binary Analysis), das das DPI-Framework (Dynamic Binary Instrumentation) verwendet, um die Speicherzuordnung zu überprüfen, Deadlocks zu erkennen und die Anwendungen zu profilieren. Das DPI-Framework verfügt über einen eigenen Low-Level-Speichermanager, Scheduler, Thread-Handler und Signal-Handler. Die Valgrind Tool Suite enthält Tools wie
Das Valgrind-Tool verwendet einen Disassemblierungs- und Resynthesemechanismus, bei dem die Anwendung in einen Prozess geladen, der Anwendungscode zerlegt, der Instrumentierungscode zur Analyse hinzugefügt, wieder zusammengesetzt und die Anwendung ausgeführt wird. Es verwendet Just Intime Compiler (JIT), um die Anwendung mit dem Instrumentierungscode einzubetten.
Valgrind Core zerlegt den Anwendungscode und übergibt das Codefragment zur Instrumentierung an das Tool-Plugin. Das Tool-Plugin fügt den Analysecode hinzu und setzt ihn wieder zusammen. Somit bietet Valgrind die Flexibilität, unser eigenes Tool über das Valgrind-Framework zu schreiben. Valgrind verwendet Schattenregister und Schattenspeicher, um Lese- / Schreibanweisungen, Lese- / Schreibsystemaufrufe, Stapel- und Heapzuordnungen zu instrumentieren.
Valgrind stellt Wrapper um den Systemaufruf bereit und registriert sich für Vor- und Nachrückrufe für jeden Systemaufruf, um den Speicher zu verfolgen, auf den im Rahmen des Systemaufrufs zugegriffen wird. Somit ist Valgrind eine Betriebssystemabstraktionsschicht zwischen dem Linux-Betriebssystem und der Clientanwendung.
Das Diagramm zeigt die 8 Phasen von Valgrind:
quelle
valgrind bildet eine Ebene zwischen Ihrem Programm und dem Betriebssystem, fängt Aufrufe an das Betriebssystem ab, fordert die Speicher- (De-) Zuweisung an und zeichnet auf, was manipuliert wird, bevor der Speicher tatsächlich zugewiesen und ein Äquivalent zurückgegeben wird. Es ist im Wesentlichen die Funktionsweise der meisten Codeprofiler, außer auf einer viel niedrigeren Ebene (Systemaufrufe anstelle von Programmfunktionsaufrufen).
quelle
Hier finden Sie einige nette Infos:
Machen Sie sich außerdem mit LD_PRELOAD vertraut.
quelle
Valgrind ist im Grunde eine virtuelle Maschine , die Ihr Programm ausführt. Es ist eine virtuelle Architektur, die jeden Aufruf abfängt, um Speicher zuzuweisen / freizugeben.
quelle