Как разбить в GDB на основе содержимого массива? - PullRequest
2 голосов
/ 18 марта 2020

Я пытаюсь поместить условную точку останова в функцию, которая проверяет содержимое массива. Моя идея состояла в том, чтобы использовать memcmp() в условии:

typedef struct {
    uint8_t arr[4];
} arg_t;

Затем в GDB (объявление встроенного массива):

b func() if memcmp(arg.arr, (uint8_t[]){1, 2, 3, 4}, sizeof(arg.arr)) == 0

Однако это не работает:

(gdb) c
Continuing.
Error in testing breakpoint condition:
Too many array elements

Я могу сделать это с if arg.arr[0] == 1 && arg.arr[1] == 2 && ..., но в моем реальном случае доступ к массиву (содержащему адрес IPv6) довольно запутан, поэтому он довольно быстро становится громоздким.

ОБНОВЛЕНИЕ : После комментария Марка я попробовал следующую тестовую программу:

#include <stdio.h>
#include <stdint.h>
#include <string.h>

int main(void) {
  uint8_t a[] = { 1, 2, 3, 4 };
  printf("memcmp returns %d\n", memcmp(a, (uint8_t[4]){1,2,3,4}, sizeof(a)));
  return 0;
}                

После компиляции я поместил условный разрыв в возвращение, используя явный синтаксис размера массива, и он работал, но не работает кажется, что все останавливается, как и ожидалось:

(gdb) br hello.c:8 if memcmp(a, (uint8_t[4]){1,2,3,4}, sizeof(a)) == 0
Breakpoint 1 at 0x75c: file hello.c, line 8.
(gdb) run
Starting program: /mnt/c/stuff/src/test/hello
memcmp returns 0
[Inferior 1 (process 153) exited normally]

Я пытался вручную оценить возвращаемое значение функции на месте разрыва:

(gdb) br hello.c:8
Note: breakpoint 1 also set at pc 0x800075c.
Breakpoint 2 at 0x800075c: file hello.c, line 8.
(gdb) dele 1
(gdb) run
Starting program: /mnt/c/stuff/src/test/hello
memcmp returns 0

Breakpoint 2, main () at hello.c:8
8       return 0;
(gdb) p  memcmp(a, (uint8_t[4]){1,2,3,4}, sizeof(a))
$1 = (int (*)(const void *, const void *, size_t)) 0x7fffff18aba0 <__memcmp_avx2_movbe>

Я был удивлен, увидев это, я подозреваю это может быть связано с тем, что memcmp () является компилятором intrinsi c для инструкции avx2, и в этом случае мне может понадобиться как-то привести его?

1 Ответ

0 голосов
/ 18 марта 2020

Возможно, это не то, что вам нужно, но для сложных тестов я помогаю программе gdb, добавив несколько процедур проверки.


Метод 1:

I создать void checkon (void) { if (expr_to_stop_on) badnews(); }

И затем: void badnews { stopme = 1; }

Затем я набираю код с вызовами checkon

Затем я говорю gdb сделать b badnews.


Метод 2:

Альтернативой может быть создание: int checkfail(void) { return expr_to_stop_on; }

Затем скажите gdb to watch myarray.

Это создает точку наблюдения (с помощью H / W Assist). Точка наблюдения похожа на точку останова.

Затем вы можете сделать: cond 1 checkfail()


Метод 3:

Аналогично методу 2, но вместо точки наблюдения, используйте точку трассировки [с той же командой cond (на самом деле вам может потребоваться использовать actions вместо этого).

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

Это может быть медленно , потому что каждая строка должна делать эти вещи.

Я думаю, что метод 2, вероятно, лучшая ставка.

...