Как бороться с одной строкой, заключенной в несколько строк в GDB? - PullRequest
0 голосов
/ 02 июня 2019

Например,

int main()
{
        int aa = 1, bb =2, cc = 3;
        int dd = ( (aa + 3 - 1)
                 / bb)
                 << cc;                                                                                                          
        printf("%d\n", dd);
        return 1;
}

Так что я разбиваю int dd строку на несколько строк просто для демонстрации.

Затем я использую gdb для отладки.

Breakpoint 1, main () at a.c:25
25              int aa = 1, bb =2, cc = 3;
(gdb) n
26              int dd = ( (aa + 3 - 1)
(gdb) n
27                       / bb)
(gdb) n
26              int dd = ( (aa + 3 - 1)
(gdb) n
29              printf("%d\n", dd);
(gdb) n
8
30              return 1;

Как видите, int dd показывается несколько раз, а << cc не отображается.

Как этого избежать?Например, когда я набираю n и ввожу, gdb показывает полную строку int dd один раз, а когда я снова набираю n, gdb переходит к следующей строке?

1 Ответ

0 голосов
/ 02 июня 2019

Из GDB вы ничего не можете сделать, потому что он просто следует отладочной информации, генерируемой компилятором.Вы можете увидеть вывод сборки с помощью gcc -g -S -fverbose-asm -fno-dwarf2-cfi-asm -o - main.c.Благодаря аннотациям вы сможете получить суть этого, даже если вы не знаете ассемблер.

Вот выдержка:

# main.c:4:         int dd = ( (aa + 3 - 1)
    movl    -4(%rbp), %eax  # aa, tmp91
    addl    $2, %eax    #, _1
# main.c:5:                  / bb)
    cltd
    idivl   -8(%rbp)    # bb
    movl    %eax, %edx  # tmp92, _2
# main.c:4:         int dd = ( (aa + 3 - 1)
    movl    -12(%rbp), %eax # cc, tmp94
    movl    %eax, %ecx  # tmp94, tmp99
    sall    %cl, %edx   # tmp99, _2
    movl    %edx, %eax  # _2, tmp95
    movl    %eax, -16(%rbp) # tmp95, dd

Последний блок эквивалентен

int dd = _2 << cc;

Поскольку результат операции должен где-то храниться, сдвиг и присвоение не разделяются.Ссылка на строку, содержащую присвоение.

Вы должны переписать код, чтобы иметь одну операцию на оператор:

int t1 = (aa + 3 - 1);
int t2 = t1 / bb;
int dd = t2 << cc;

Вот соответствующая сборка:

# main.c:4:     int t1 = (aa + 3 - 1);
    movl    -4(%rbp), %eax  # aa, tmp92
    addl    $2, %eax    #, tmp91
    movl    %eax, -16(%rbp) # tmp91, t1
# main.c:5:     int t2 = t1 / bb;
    movl    -16(%rbp), %eax # t1, tmp96
    cltd
    idivl   -8(%rbp)    # bb
    movl    %eax, -20(%rbp) # tmp94, t2
# main.c:6:     int dd = t2 << cc;
    movl    -12(%rbp), %eax # cc, tmp100
    movl    -20(%rbp), %edx # t2, tmp102
    movl    %eax, %ecx  # tmp100, tmp106
    sall    %cl, %edx   # tmp106, tmp102
    movl    %edx, %eax  # tmp102, tmp101
    movl    %eax, -24(%rbp) # tmp101, dd

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...