Wie wird eine bestimmte Aktion ausgeführt, wenn ein bestimmter Haltepunkt in GDB erreicht wird?

Lesezeit: 4 Minuten

Benutzeravatar von Thangaraj
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---

    – Gänseblümchen

    29. Juni 2014 um 6:51 Uhr

  • Link zu GDB-Dokumenten.

    – Benutzer202729

    16. Juni 2018 um 11:01 Uhr

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.

    – thomasa88

    14. September 2020 um 6:19 Uhr

Ciro Santilli Benutzeravatar von OurBigBook.com
Ciro Santilli OurBigBook.com

dprintf (Dynamisch printf)

https://sourceware.org/gdb/onlinedocs/gdb/Dynamic-Printf.html

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;
}

Dann:

gcc -ggdb3 -O0 -std=c99 -o main main.c
gdb -batch --nh -q -ex 'dprintf 10, "%u %u\n", i, r' -ex 'run' ./main

Ausgabe:

Dprintf 1 at 0x400545: file main.c, line 10.
0 0
1 17
2 256
3 6933
4 277346
5 14699371
6 970158528
7 3628079733
8 3070853710
9 317092431
3057168588
[Inferior 1 (process 14305) exited normally]

Getestet in Ubuntu 16.04, GDB 8.2.

1416330cookie-checkWie wird eine bestimmte Aktion ausgeführt, wenn ein bestimmter Haltepunkt in GDB erreicht wird?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy