Wie wird eine bestimmte Aktion ausgeführt, wenn ein bestimmter Haltepunkt in GDB erreicht wird?
Lesezeit: 4 Minuten
Thangaraj
Ich suche nach einer Möglichkeit, etwas zu tun, wenn ein bestimmter Haltepunkt in gdb erreicht wird.
Grundsätzlich habe ich einige Memleak in meinem Programm. Wenn die Funktion malloc und free zutrifft, muss ich in die Funktion (Schritt) eintreten und einige grundlegende Informationen wie Adresse und Größe sammeln (im Grunde gibt es dort Werte aus). Wenn Sie fertig sind, setzen Sie mein Programm fort.
Haben wir eine gute Möglichkeit, dies zu tun?
So könnten Sie zum Beispiel Breakpoint-Befehle verwenden, um den Wert von x am Eingang in foo auszugeben, wenn x positiv ist.
break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
Wenn der erste Befehl, den Sie in einer Befehlsliste angeben, ist silent, wird die übliche Meldung über das Stoppen an einem Haltepunkt nicht gedruckt. Dies kann für Haltepunkte wünschenswert sein, die eine bestimmte Nachricht ausgeben und dann fortfahren sollen. Wenn keiner der verbleibenden Befehle etwas ausgibt, sehen Sie kein Zeichen dafür, dass der Haltepunkt erreicht wurde. silent ist nur am Anfang einer Breakpoint-Befehlsliste sinnvoll.
Eine Anwendung für Haltepunktbefehle besteht darin, einen Fehler zu kompensieren, damit Sie einen anderen testen können. Setzen Sie einen Haltepunkt direkt nach der fehlerhaften Codezeile, geben Sie ihm eine Bedingung, um den Fall zu erkennen, in dem etwas Fehlerhaftes passiert ist, und geben Sie ihm Befehle, um allen Variablen, die sie benötigen, korrekte Werte zuzuweisen. Beenden Sie mit dem Continue-Befehl, damit Ihr Programm nicht anhält, und beginnen Sie mit dem Silent-Befehl, damit keine Ausgabe erfolgt. Hier ist ein Beispiel:
break 403
commands
silent
set x = y + 4
cont
end
Danke Fredrik. Aber hier ist der Variablenname richtig unbekannt. Angenommen, ich habe 1 GB Code. was sollten wir dann tun? Gibt es eine generische Methode, dies zu tun?
– Thangaraj
29. Juni 2011 um 11:22 Uhr
@Thangaraj, wenn Sie ein Memleak haben, schauen Sie es sich an valgrind wahrscheinlich DAS beste Tool zum Auffinden von Speicherlecks und sehr einfach zu bedienen!
– Fredrik Pihl
29. Juni 2011 um 16:03 Uhr
Danke. valgrind hilft mir im Falle eines Speicherlecks. aber im Allgemeinen gibt es einen anderen Weg, um dies zu erreichen. Nur zum erkunden…
– Thangaraj
30. Juni 2011 um 5:50 Uhr
Wissen Sie, wie Sie verhindern können, dass GDB auffordert? Ich meinte diese Nachrichten Type <return> to continue, or q <return> to quit---
Um Fredriks Antwort zu verdeutlichen, commands (oder nur command, wie es scheint) weiß automatisch, dass Sie gerade einen Haltepunkt gesetzt haben. Das heißt, was Fredrik zeigt, ist keine Mehrfachlinie break Befehl, es sind zwei separate Befehle: breakund commands. Es sieht aus wie das:
(gdb) break 989
Breakpoint 23 at 0x7fffe2761dac: file foo.cpp, line 989.
(gdb) command
Type commands for breakpoint(s) 23, one per line.
End with a line saying just "end".
>silent
>print result
>end
(gdb) c
Continuing.
$79 = {elems = {0, 0}}
(gdb)
Befehl vs. Befehle: GCC erlaubt Ihnen, nur das Präfix des Befehls zu schreiben, solange es eindeutig ist. Auch für andere: “Hilfebefehle” zeigt, dass man den Haltepunkt angeben kann, auf den die Bedingung gesetzt werden soll.
Dies ist die bequemste Lösung für den speziellen Fall des Druckens von Dingen:
dprintf <line>, "%u\n", variable
Es könnte auch schneller sein als commands da es Code kompilieren und einfügen könnte, anstatt die Kontrolle an GDB zurückzugeben, um beliebige Befehlszeichenfolgen zu interpretieren, was extrem langsam ist. TODO Ich weiß nicht, ob dies tatsächlich getan wird. dprintf vs commands: Was ist der Unterschied zwischen dprintf vs break + Befehlen + Continue?
Ausführliches Beispiel:
Haupt c
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
uint32_t i;
uint32_t r = 0;
for (i = 0; i < 10; ++i) {
r += i*i + 13*r*i + 17; /* LINE 10. */
}
printf("%" PRIu32 "\n", r);
return EXIT_SUCCESS;
}