我尝试使用gdb调试上面的代码。我面临的问题是,当我使用命令break main时,它在第5行设置断点,而不是在第2行设置断点。下面是我得到的输出:
break main
(gdb) break main Breakpoint 1 at 0x555555555141: file firstprogram.c, line 5.
我希望断点设置在第2行而不是第5行。
nvbavucw1#
只能在有指令的地址设置断点。看看你的编译器是如何把这个C函数转换成asm的。(例如,在Godbolt上,用当前的GCC/clang针对Linux。)在GCC或clang的输出中,无论是否经过优化,都有函数序言的指令(分别是压入调用保留寄存器或使用帧指针生成堆栈帧)。GCC和clang生成的调试信息将这些指令与{的第3行相关联。(The Godbolt编译器资源管理器的颜色语法高亮显示和鼠标悬停高亮显示是基于编译器生成的调试信息,GDB在将源代码行Map到地址或从地址Map源代码行时使用相同的信息。函数体中任何内容的第一条指令要么是未优化版本中的i=0,要么是循环体中的mov edi, OFFSET FLAT:.LC0/call puts。(GCC/clang认为mov ebx, 11循环计数器init与源代码行无关,因为在优化之后,他们已经将循环转换为在11次迭代中递减计数到零。根据调试信息,mov-to-register指令是函数序言的一部分。)
{
i=0
mov edi, OFFSET FLAT:.LC0
call puts
mov ebx, 11
1条答案
按热度按时间nvbavucw1#
只能在有指令的地址设置断点。
看看你的编译器是如何把这个C函数转换成asm的。(例如,在Godbolt上,用当前的GCC/clang针对Linux。)
在GCC或clang的输出中,无论是否经过优化,都有函数序言的指令(分别是压入调用保留寄存器或使用帧指针生成堆栈帧)。GCC和clang生成的调试信息将这些指令与
{
的第3行相关联。(The Godbolt编译器资源管理器的颜色语法高亮显示和鼠标悬停高亮显示是基于编译器生成的调试信息,GDB在将源代码行Map到地址或从地址Map源代码行时使用相同的信息。
函数体中任何内容的第一条指令要么是未优化版本中的
i=0
,要么是循环体中的mov edi, OFFSET FLAT:.LC0
/call puts
。(GCC/clang认为
mov ebx, 11
循环计数器init与源代码行无关,因为在优化之后,他们已经将循环转换为在11次迭代中递减计数到零。根据调试信息,mov-to-register指令是函数序言的一部分。)