Ответ 1
Настройка точки останова на abort()
представляется лучшим ответом.
break abort
в gdb CLI.
Я пытаюсь захватить неудачные утверждения в моей программе. Я использую библиотеку, которая делает прямые вызовы assert(), а не пользовательскую функцию или макрос, и именно в этой библиотеке я в настоящее время пытаюсь отслеживать несколько ошибок, связанных с переносом. Все задействованное было скомпилировано с символами отладки в g++.
Лучшее решение, которое я нашел, ломается в файле: строка assert, с условием выражения assert. Это позволяет останавливаться на утверждении, прежде чем он терпит неудачу, но является ужасным решением. Это требует специальной настройки для каждого возможного утверждения, не работает из моей IDE, и в целом это слишком много усилий.
Как я могу поработать с любым неудавшимся утверждением с использованием gdb и gcc таким образом, чтобы разрешить проверку столбца и переменных в пределах действия вызова assert?
Было бы еще лучше, если бы решение разрешило мне отказаться от отказа и продолжить работу.
Настройка точки останова на abort()
представляется лучшим ответом.
break abort
в gdb CLI.
В 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.
Если предложенные выше ответы у вас не работают, вы можете попытаться отключить функцию __assert_fail.
break __assert_fail
Скорее всего, имя зависит от реализации, но его легко найти, если вы посмотрите определение макроса assert на вашей платформе. Это позволит вам сломаться до SIGABRT.