Подтвердить что ты не робот

Каков правильный способ провалить неудачные утверждения в gdb?

Я пытаюсь захватить неудачные утверждения в моей программе. Я использую библиотеку, которая делает прямые вызовы assert(), а не пользовательскую функцию или макрос, и именно в этой библиотеке я в настоящее время пытаюсь отслеживать несколько ошибок, связанных с переносом. Все задействованное было скомпилировано с символами отладки в g++.

Лучшее решение, которое я нашел, ломается в файле: строка assert, с условием выражения assert. Это позволяет останавливаться на утверждении, прежде чем он терпит неудачу, но является ужасным решением. Это требует специальной настройки для каждого возможного утверждения, не работает из моей IDE, и в целом это слишком много усилий.

Как я могу поработать с любым неудавшимся утверждением с использованием gdb и gcc таким образом, чтобы разрешить проверку столбца и переменных в пределах действия вызова assert?

Было бы еще лучше, если бы решение разрешило мне отказаться от отказа и продолжить работу.

4b9b3361

Ответ 1

Настройка точки останова на abort() представляется лучшим ответом.

break abort в gdb CLI.

Ответ 2

В Linux break не требуется, просто введите bt строке

abort() вызывает SIGABRT сигнала SIGABRT в Linux, и GDB по умолчанию уже прерывает сигналы. Например:

переменный ток

#include <assert.h>

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

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

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

Затем:

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

Затем просто введите bt в оболочке:

(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

Который уже показывает значения функции (f (i=1)).

И вы также можете сделать как обычно:

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

Параметр, который контролирует, прерывает ли GDB сигнал по умолчанию или нет: handle all nostop как показано в handle all nostop: Как обрабатывать все сигналы в GDB

Протестировано в Ubuntu 16.10, gdb 7.11.

Ответ 3

Если предложенные выше ответы у вас не работают, вы можете попытаться отключить функцию __assert_fail.

break __assert_fail

Скорее всего, имя зависит от реализации, но его легко найти, если вы посмотрите определение макроса assert на вашей платформе. Это позволит вам сломаться до SIGABRT.