在GDB中,info registers
或info all-registers
会显示所有注册符号名称及其值。
问题:
如何获取存储在该寄存器中的变量名称(即来自源代码)? (或源代码中的行号,或任何其他内容)
例如:
int my_reg = /* something */;
float another_reg = /* something else */;
...
然后,info all-registers
可能会返回:
R0 0x0 0
R1 0xfffbf0 16776176
R2 0x0 0
R3 0x0 0
R4 0x6 6
如何确定哪个寄存器(R0?R2?R4?)与my_reg
“关联”?
答案 0 :(得分:2)
在任何给定的时间点,可能有一个寄存器,多个寄存器,甚至没有与任何给定C变量相关的寄存器。你必须检查反汇编,看看发生了什么。
为什么不只是print my_reg
才能看到价值?
l *$pc
将列出正在执行的当前指令的源代码。
答案 1 :(得分:2)
如果您可以访问调试符号(并了解如何读取它们 - 也就是说,您有一些代码可以解析调试符号),则可以准确地跟踪哪个寄存器对应于哪个寄存器。然而,由于编译器决定出于某种原因移动事物(例如,一些计算从R1开始,最终结果在R2中,因为这比尝试更好),因此很可能从一行更改为下一行。保留R1中的值[或者我们也需要R1中的原始值 - 想想array[x++]
- 现在我们有x
的新值,希望在寄存器中,以及旧{{1}的值我们需要用于索引,也需要在寄存器中添加到x
的基址。
并非所有变量都以寄存器结尾(取决于处理器和“可用的寄存器”)。
调试器将知道每个变量在任何给定时间的位置 - 但有时它可能会很困惑,例如:
array
在优化过程中,可能会转换为类似内容:
int array[10000];
...
for(int i = 0; i < 10000; i++)
{
array[i] = rand();
}
现在尝试打印int array[10000];
int *ptr = array;
int *ptr2 = &array[10000];
while(ptr < ptr2)
{
*ptr++ = rand();
}
...;)