首页 > 解决方案 > 如何处理在gdb中包裹成多行的单行?

问题描述

例如,

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 转到下一行?

标签: cgdb

解决方案


在 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

它与以前基本相同,但现在块与语句完美匹配。您无法控制编译器的输出,但它会尝试保留语句之间的边界,因此这是您的最佳选择。


推荐阅读