如何检查我的调试器的程序计数器是否在函数内部?

How to check if my debugger's program counter is inside a function?

我正在编写一个调试器,想看看它的程序计数器是否在函数内部。我想我需要检查它是否在 DW_AT_low_pcDW_AT_high_pc 之间。这是我要调试的代码:

void myPrint()
{
    int test_a = 3;
    int test_b = 2;

    printf( "myPrint: sum: %d\n", test_a + test_b );
}

int main( void )
{
    myPrint();

    return 0;
}

dwarfdump 给出以下内容:

< 1><0x0000033d>    DW_TAG_subprogram
                      DW_AT_external              yes(1)
                      DW_AT_name                  myPrint
                      DW_AT_decl_file             0x00000001 /home/glaze/Documents/src/debugger/test_input.c
                      DW_AT_decl_line             0x0000000d
                      DW_AT_decl_column           0x00000006
                      DW_AT_low_pc                0x00001181
                      DW_AT_high_pc               <offset-from-lowpc>66
                      DW_AT_frame_base            len 0x0001: 9c: DW_OP_call_frame_cfa
                      DW_AT_GNU_all_tail_call_sites yes(1)
                      DW_AT_sibling               <0x0000037a>

在我的调试器循环中,我读取程序计数器如下:

    struct user_regs_struct regs;
    if (ptrace( PTRACE_GETREGS, pid, 0, &regs ) == -1)
    {
        printf( "%s", strerror( errno ) );
        return 1;
    }

    Elf64_Addr programCounter = regs.rip;

但它得到的值永远不会在 DW_AT_low_pcDW_AT_high_pc 之间,例如 0x7f9b94c95100.

我已经可以在调试器程序中以编程方式读取 DW_AT_low_pcDW_AT_high_pc,它报告的值与 dwarfdump.

相同

如何检查我的程序计数器是否在 myPrint 函数内?

我通过读取 /proc/pid/maps 的第一行并将其添加到 DW_AT_low_pc 来获取程序的基地址来解决这个问题。 DW_AT_high_pcDW_AT_low_pc.

的偏移量

然后在我的调试器循环中我 运行 它单步执行

ptrace( PTRACE_SINGLESTEP, pid, NULL, NULL );

在每次迭代中,我检查程序计数器 regs.rip 在函数地址 运行ge.

之间

当我使用 -g -fno-pic -O0 -fPIE 编译测试程序并在调试器程序禁用地址 space 运行domization 时调试问题更容易,方法是在 personality( ADDR_NO_RANDOMIZE ); 之前调用 personality( ADDR_NO_RANDOMIZE ); =18=]。我还通过编写一个简单的添加循环使测试程序变得更加复杂,这样它除了调用地址在我的可执行文件之外的 printf() 之类的库例程之外还可以执行其他操作。