2009-02-17 7 views
6

Ich versuche, ein kleines Betriebssystem zu debuggen, das ich in einem Universitätskurs in C++ geschrieben habe. Zur Laufzeit wird irgendwo eines meiner Objekte beschädigt. Es scheint, dass dies passiert, weil versehentlich in die falsche Speicheradresse geschrieben wurde. Da ich nicht in der Lage bin, den Ort zu finden, an dem dies passiert, wenn ich den Code rein betrachte, brauche ich einen anderen Weg.Tracing Schreibzugriff auf Klasseninstanz/Speicherbereich in gdb

Da dies ein Betriebssystem ist, kann ich keine Tools wie Valgrind anhängen, aber ich kann es in Emulatoren (Bochs/Qemu) mit gdb angeschlossen ausführen.

Gibt es in gdb eine Möglichkeit, den Schreibzugriff auf eine Klasseninstanz oder allgemeiner einen bestimmten Speicherbereich zu verfolgen? Ich würde gerne brechen, sobald der Schreibzugriff eintritt, damit ich überprüfen kann, ob das gültig ist oder nicht.

+0

verwandt: https://stackoverflow.com/questions/11004374/watch-a-memory-range-in-gdb –

Antwort

8

können Sie Beobachtungspunkte setzen:

watch x 

Dies wird brechen, wenn x modifiziert wird. x kann jede Art von Variable sein. Wenn Sie haben:

class A; 
A x; 

Dann bricht gdb, wenn x geändert wird.

Sie können tatsächlich einen Watchpoint auf einen Ausdruck setzen, und gdb bricht, wenn sich der Ausdruck ändert. Seien Sie vorsichtig damit, denn wenn der Ausdruck nicht etwas ist, was die zugrunde liegende Hardware unterstützt, muss gdb dies nach jeder Anweisung auswerten, was zu einer schrecklichen Leistung führt. Zum Beispiel, wenn A oben ist eine Klasse mit vielen Mitgliedern kann dann gdb die gesamte Instanz beobachten x, aber die Art und Weise, es wird ist Arbeit:

  • ausführen einen Befehl
  • Sprung zum Debug-Haltepunkt
  • überprüfen, ob x hat
  • Rückkehr zum Programm
  • geändert

das ist natürlich sehr langsam. Wenn x ein int ist, kann GDB einen Hardware-Haltepunkt verwenden.

Wenn Sie eine bestimmte Speicheradresse haben, können Sie es sehen:

watch *0x1234 

Diese brechen wird, wenn der Inhalt von [0x1234] Änderungen.

Sie können auch einen Lese-Haltepunkt mithilfe von rwatch oder awatch festlegen, um einen Lese-/Schreib-Haltepunkt festzulegen.

+0

Können Sie eine Reihe von Adressen beobachten? Ich bin in einer ähnlichen Situation, außer ich würde gerne meinen gesamten Kernel-Stack ansehen (ich denke, irgendwann schreibe ich aus Versehen, was zur Hölle führt) – Mala

+0

@Mala: Du kannst das nicht machen x86 mit Hardware-Watchpoints.Abgesehen davon, dass ich die Adressen explizit spezifiziere, weiß ich nicht, wie man überhaupt einen Bereich von Adressen beobachtet. Vielleicht sollten Sie das als separate Frage stellen. –

3

Wenn Sie zumindest ungefähr wissen, wo es passiert, können Sie einfach "display" anstelle von watch verwenden und manuell Schritt für Schritt vorgehen, bis Sie sehen, wann die Änderung passiert. Eine Adresse mit "watch" zu sehen ist einfach zu schmerzhaft langsam.

+1

Tatsächlich ist das Anschauen nur einer Adresse sehr schnell, weil es durch Hardware erfolgt. Etwas anderes zu sehen kann sehr schmerzhaft werden –