Как бороться с `__int128` в gdb? - PullRequest
0 голосов
/ 13 мая 2018

В настоящее время я борюсь с GDB, чтобы иметь дело с GCC-специфическим типом __int128 в GDB.Мне удается выполнить несколько вычислений на лету, таких как:

(gdb) p /x (__int128) (1 << (8 * 8))
$1 = 0x00000000000000000000000000000001
(gdb) ptype bitmask
type = const __int128 unsigned

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

(gdb) p /x ((((__int128) 1) << (8 * 8)) - 1)
That operation is not available on integers of more than 8 bytes.
(gdb) p /x (__int128) 0xfffffffffffffffffffffffff
Numeric constant too large.

Итак, есть ли способ оценить такое выражение на __int128 в GDB?

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Если вам просто нужно вывести постоянное значение, идея py print(expr128) работает фантастически благодаря произвольной целочисленной точности Python.

Если, однако, вам нужно работать с фактической переменной C типа __int128, вам потребуется временно преобразовать ее во что-то вроде unsigned long long[2], чтобы выполнять операции с ней в GDB, но помните, что вы затем работа с массивом из 2 64-битных значений, поэтому X[0] << 64 не будет работать так, как с истинным 128-битным типом __int128. GDB может распечатать значение; он просто не может манипулировать своими битами. GCC позволяет манипулировать его битами; ваш libc просто не может напечатать значение, используя printf, и может даже не быть какого-либо специфичного для GCC кода, позволяющего это сделать.

Вот пример сеанса оболочки, показывающий, насколько проблематичен этот специфичный для компилятора тип в GDB:

$ nl bar.c
    1   int main(void)
    2   {
    3       __int128 v = 1;
    4       v <<= 62;
    5       v <<= 2;
    6   }
$ gcc -g -o bar bar.c
$ gdb -q ./bar
Reading symbols from ./bar...done.
(gdb) break 5
Breakpoint 1 at 0x5e8: file bar.c, line 5.
(gdb) run
Starting program: /home/luser/bar

Breakpoint 1, main () at bar.c:5
5       v <<= 2;
(gdb) print/x *(long long(*)[2])&v
$1 = {0x4000000000000000, 0x0}
(gdb) print/x (*(long long(*)[2])&v)[0]+1
$2 = {0x4000000000000001, 0x0}
(gdb) next
6   }
(gdb) print/x *(long long(*)[2])&v
$3 = {0x0, 0x1}
(gdb) print/x (*(long long(*)[2])&v)[0]+1
$4 = {0x1, 0x1}

Принимая во внимание младший процессор моей машины, результаты (вроде) ясны:

$1 = 0x0000 0000 0000 0000
       4000 0000 0000 0000  # 1<<62
$2 = 0x0000 0000 0000 0000
       4000 0000 0000 0001  #(1<<62) + 1
$3 = 0x0000 0000 0000 0001
       0000 0000 0000 0000  # 1<<64
$4 = 0x0000 0000 0000 0001
       0000 0000 0000 0001  #(1<<64) + 1

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

Мое предложение: ссылка в некоторых арифметических процедурах, которые работают со значениями __int128, для облегчения отладки, поэтому вы можете использовать такие вещи, как call negate128 (value) в GDB, чтобы получить результат выражения C -value, где value имеет тип __int128. Также не нужно проверять переполнение, так как машина будет обрабатывать это для вас, как это было бы с любым другим типом, поэтому продолжайте и напишите такие вещи (если вы работаете с системой, в которой переполнение не убивает вашу программу или всю машина):

__int128 add128(__int128 a, __int128 b) { return a + b; }
__int128 sub128(__int128 a, __int128 b) { return a - b; }
__int128 shl128(__int128 a, int n) { return a << n; }
__int128 shr128(__int128 a, int n) { return a >> n; }
0 голосов
/ 14 мая 2018

Итак, есть ли способ оценить такое выражение на 128 в GDB

Не напрямую, но вы можете использовать встроенный python (с его неограниченной точностью) для достижения несколько эквивалентного результата:

(gdb) py print('0x%x' % ((1 << (8 * 8)) - 1))
0xffffffffffffffff

(gdb) py print('0x%x' % ((1 << (8 * 8 + 5)) + 1))
0x200000000000000001
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...