2010-03-15 7 views
12

Auf einem großen C-Anwendung, ich habe eine Hardware-Beobachtungspunkt auf einer Speicheradresse wie folgt festgelegt:GDB Hardware Watchpoint sehr langsam - warum?

(gdb) watch *0x12F5D58 
Hardware watchpoint 3: *0x12F5D58 

Wie Sie sehen, es ist ein Hardware-Beobachtungspunkt, keine Software, die die Langsamkeit erklären würde.

Jetzt hat sich die Laufzeit der Anwendung unter Debugger von weniger als zehn Sekunden auf eine Stunde geändert und gezählt. Der Watchpoint hat bisher dreimal ausgelöst, das erste Mal nach 15 Minuten, als die Speicherseite mit der Adresse von sbrk lesbar gemacht wurde. Während dieser 15 Minuten sollte der Watchpoint effizient sein, da die Speicherseite nicht zugänglich war. Und das erklärt immer noch nicht, warum es danach so langsam ist.

Die Plattform ist x86_64 und die GDB-Versionen sind Ubuntu 9.10 Paket:

$ gdb --version 
GNU gdb (GDB) 7.0-ubuntu 
[...] 

und Lager GDB 7.1 aus Quellen gebaut:

$ gdb-7.1 --version 
GNU gdb (GDB) 7.1 

Vielen Dank im Voraus für alle Ideen, was das sein könnte Ursache oder wie man es repariert/umgeht.

EDIT: entfernt werfen

EDIT: GDB 7.1

+0

Ist es immer langsam, wenn es unter dem Debugger läuft oder nur wenn Sie einen Watchpoint gesetzt haben? – Gabe

+1

Nur mit Watchpoint. –

Antwort

5

Ich hatte tatsächlich Probleme mit Hardware-Watchpoints in GDB 7.x.x, was nicht akzeptabel ist, da Watchpoints in meinem Job eine Notwendigkeit sind.

Auf Anraten eines Kollegen habe ich die Quelle für 6.7.1 heruntergeladen und lokal erstellt. Watchpoints funktionieren jetzt viel besser.

Könnte einen Versuch wert sein.

+0

Interessant. Ich werde das ausprobieren. –

+1

GDB 6.7.1 fehlt eine Funktion, bei der Watchpoints auf Speicheradressen verwendet werden können, auf die bei der Einrichtung des Watchpoints nicht zugegriffen werden kann. Es ist möglich, es zur richtigen Zeit zu aktivieren, aber das wird mehr beteiligt sein, werde ich später versuchen. Ich habe auch gerade versucht, GDB 7.1 zu veröffentlichen, dasselbe Problem wie bei 7.0. –

+0

mit bedingten Breakpoints und Breakpoint-Befehlen können Sie ohne großen Aufwand umgehen. – alesplin

4

Es ist sehr wahrscheinlich, weil Sie es jedes Mal sind Gießen. Versuchen Sie folgendes:

(gdb) watch *0x12F5D58 

Eine weitere Option ist, dass Sie zu viele Hardware-Beobachtungspunkte gesetzt haben, so gdb gezwungen ist, Software Beobachtungspunkte zu verwenden. Überprüfe, wie viele Watchpoints du benutzt hast:

und schau ob du einige Watchpoints deaktivieren kannst.

+0

Kann gdb wirklich ein Integer-Literal dereferenzieren, ohne zu wissen, welcher Typ als dereferenziert werden soll? Das ist kein gültiger C-Ausdruck, zumindest ... – unwind

+0

Ja, kann es. Das mache ich die ganze Zeit. –

+1

Zu meiner Überraschung (ich dachte, GDB akzeptiert nur C-Ausdrücke) "watch * 0x12F5DF8" funktioniert, ist aber so langsam wie die vorherige Version. –

1

Auf x86 haben Sie die folgende Einschränkung: alle Ihre Watchpoints können nicht mehr als vier Speicheradressen abdecken, jede Speicheradresse kann nach einem Speicherwort suchen - weil die Hardware-Watchpoints (die schnellen) die Debugregister des Prozessors verwenden Sie haben vier, also vier Standorte, auf die Sie achten müssen.

+1

Er sagte bereits, dass er nur einen einzigen Watchpoint hatte, siehe den vierten Kommentar zu Nathans Antwort. –

5

Ich entdeckte, dass das Beobachten eines großen Zeichenpuffers sehr langsam war, während das Beobachten eines Charakters in diesem Puffer sehr schnell war.

z.B.

static char buf[1024]; 
static char* buf_address = &buf; 

watch buf_address - quälend langsam.

watch *buf_address - sehr schnell.