Выполнять определенные действия, когда определенные точки останова в gdb
Я ищу способ сделать какое-то действие, когда конкретная точка разбивки попадает в gdb.
В основном у меня есть memleak в моей программе. Когда malloc и free function попадают, мне нужно войти в функцию (шаг) и собрать некоторую базовую информацию, такую как addr и size (в основном напечатать там значения). После завершения моей программы.
Есть ли у нас хороший способ сделать это?
Ответы
Ответ 1
Например, здесь вы можете использовать команды останова для печати значения x при входе в foo всякий раз, когда x положителен.
break foo if x>0
commands
silent
printf "x is %d\n",x
cont
end
Если первая команда, указанная в списке команд, silent
, обычное сообщение об остановке в точке останова не печатается. Это может быть желательно для контрольных точек, которые должны печатать конкретное сообщение, а затем продолжить. Если ни одна из оставшихся команд ничего не печатает, вы не видите признаков того, что точка останова достигнута. молчание имеет смысл только в начале списка команд точки останова.
Одно приложение для команд точки останова - это компенсация одной ошибки, поэтому вы можете проверить ее на другую. Положите точку останова сразу же после ошибочной строки кода, дайте ей условие, чтобы обнаружить случай, в котором что-то ошибочное, и дать ему команды назначать правильные значения любым переменным, которые в них нуждаются. Завершите с помощью команды continue, чтобы ваша программа не останавливалась, и начинайте с бесшумной команды, чтобы не производилось никакого вывода. Вот пример:
break 403
commands
silent
set x = y + 4
cont
end
Ответ 2
Чтобы уточнить ответ Фредрика, commands
(или просто command
, похоже) автоматически знает, что вы просто установили точку останова. То есть, что показывает Fredrik, это не многострочная команда break
, это две отдельные команды: break
и commands
. Это выглядит так:
(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)
Ответ 3
dprintf
(динамический printf
)
https://sourceware.org/gdb/onlinedocs/gdb/Dynamic-Printf.html
Это наиболее удобное решение для конкретного случая печати:
dprintf <line>, "%u\n", variable
Он также может быть быстрее, чем commands
, поскольку он может компилировать и вводить код вместо того, чтобы давать управление GDB для интерпретации произвольных командных строк. TODO Я не знаю, действительно ли это сделано. dprintf
vs commands
: В чем разница между dprintf и break + commands + continue?
Подробный пример:
main.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;
}
Тогда:
gcc -ggdb3 -O0 -std=c99 -o main main.c
gdb -batch -nh -q -ex 'dprintf 10, "%u %u\n", i, r' -ex 'run' ./main
Вывод:
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]
Протестировано в Ubuntu 14.04.