如何检查我的调试器的程序计数器是否在函数内部?
How to check if my debugger's program counter is inside a function?
我正在编写一个调试器,想看看它的程序计数器是否在函数内部。我想我需要检查它是否在 DW_AT_low_pc
和 DW_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, ®s ) == -1)
{
printf( "%s", strerror( errno ) );
return 1;
}
Elf64_Addr programCounter = regs.rip;
但它得到的值永远不会在 DW_AT_low_pc
和 DW_AT_high_pc
之间,例如 0x7f9b94c95100
.
我已经可以在调试器程序中以编程方式读取 DW_AT_low_pc
和 DW_AT_high_pc
,它报告的值与 dwarfdump
.
相同
如何检查我的程序计数器是否在 myPrint
函数内?
我通过读取 /proc/pid/maps
的第一行并将其添加到 DW_AT_low_pc
来获取程序的基地址来解决这个问题。 DW_AT_high_pc
是 DW_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()
之类的库例程之外还可以执行其他操作。
我正在编写一个调试器,想看看它的程序计数器是否在函数内部。我想我需要检查它是否在 DW_AT_low_pc
和 DW_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, ®s ) == -1)
{
printf( "%s", strerror( errno ) );
return 1;
}
Elf64_Addr programCounter = regs.rip;
但它得到的值永远不会在 DW_AT_low_pc
和 DW_AT_high_pc
之间,例如 0x7f9b94c95100
.
我已经可以在调试器程序中以编程方式读取 DW_AT_low_pc
和 DW_AT_high_pc
,它报告的值与 dwarfdump
.
如何检查我的程序计数器是否在 myPrint
函数内?
我通过读取 /proc/pid/maps
的第一行并将其添加到 DW_AT_low_pc
来获取程序的基地址来解决这个问题。 DW_AT_high_pc
是 DW_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()
之类的库例程之外还可以执行其他操作。