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

Выполнять определенные действия, когда определенные точки останова в gdb

Я ищу способ сделать какое-то действие, когда конкретная точка разбивки попадает в gdb.

В основном у меня есть memleak в моей программе. Когда malloc и free function попадают, мне нужно войти в функцию (шаг) и собрать некоторую базовую информацию, такую ​​как addr и size (в основном напечатать там значения). После завершения моей программы.

Есть ли у нас хороший способ сделать это?

4b9b3361

Ответ 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.