it-swarm.com.de

Was ist der richtige Weg, um fehlgeschlagene Asserts in gdb zu brechen?

Ich versuche, fehlgeschlagene Zusicherungen in meinem Programm zu erfassen. Ich verwende eine Bibliothek, die direkte Aufrufe von assert () ausführt, anstatt eine benutzerdefinierte Funktion oder ein benutzerdefiniertes Makro. In dieser Bibliothek versuche ich derzeit, mehrere portierungsbezogene Fehler aufzuspüren. Alles was dazugehört wurde mit Debug-Symbolen in g ++ kompiliert.

Die beste Lösung, die ich gefunden habe, ist das Brechen in der Datei: Zeile der Zusicherung mit der Bedingung des Zusicherungsausdrucks. Dies ermöglicht das Beenden der Assertion, bevor sie fehlschlägt, ist jedoch eine schreckliche Lösung. Es erfordert ein spezielles Setup für jede möglicherweise fehlgeschlagene Bestätigung, funktioniert nicht mit meiner IDE und ist im Allgemeinen viel zu aufwändig.

Wie kann ich any failed assert mit gdb & gcc so unterbrechen, dass der Callstack und die Variablen im Rahmen des assert-Aufrufs geprüft werden können?

Es wäre sogar noch besser, wenn die Lösung es mir ermöglichen würde, den Fehler der Zusicherung zu verwerfen und weiterzulaufen.

17
user3995702

Das Festlegen eines Haltepunkts bei abort() scheint die beste Antwort zu sein.

break abort in der gdb-CLI.

20
Peter M

Unter Linux ist keine break erforderlich. Geben Sie einfach bt an der Eingabeaufforderung ein

abort() bewirkt, dass ein Signal unter Linux ausgelöst wird, und GDB bricht bereits standardmäßig bei Signalen.

Z.B.:

#include <assert.h>

void g(int i) {
    assert(0);
}

void f(int i) {
    g(i);
}

int main(void) {
    f(1);
}

Dann:

gcc -std=c99 -O0 -ggdb3 -o a a.c
gdb -ex run ./a

Dann tippe einfach bt in die Shell:

(gdb) bt
#0  __GI_raise ([email protected]=6) at ../sysdeps/unix/sysv/linux/raise.c:58
#1  0x00007ffff7a483ea in __GI_abort () at abort.c:89
#2  0x00007ffff7a3ebb7 in __assert_fail_base (fmt=<optimized out>, [email protected]=0x555555554788 "0", [email protected]=0x555555554784 "a.c", [email protected]=4, 
    [email protected]=0x55555555478a <__PRETTY_FUNCTION__.1772> "g") at assert.c:92
#3  0x00007ffff7a3ec62 in __GI___assert_fail (assertion=0x555555554788 "0", file=0x555555554784 "a.c", line=4, function=0x55555555478a <__PRETTY_FUNCTION__.1772> "g")
    at assert.c:101
#4  0x00005555555546ca in g (i=1) at a.c:4
#5  0x00005555555546df in f (i=1) at a.c:8
#6  0x00005555555546f0 in main () at a.c:12

Welche zeigt bereits die Funktionswerte (f (i=1)).

Und Sie können es auch wie gewohnt tun:

(gdb) f 4
#4  0x00005555555546ca in g (i=1) at a.c:4
4           assert(0);
(gdb) p i
$1 = 1

Getestet in Ubuntu 16.10, gdb 7.11.

Wenn die oben genannten Antworten für Sie nicht funktionieren, können Sie versuchen, die __assert_fail-Funktion zu unterbrechen. 

break __assert_fail

Der Name ist höchstwahrscheinlich von der Implementierung abhängig, aber er ist leicht zu finden, wenn Sie die Definition des Assert-Makros auf Ihrer Plattform betrachten. Dadurch können Sie vor SIGABRT brechen.

1
Islam Boziev