在尝试调试由段错误引发的内核时,在我看来,崩溃的行实际上没有任何意义;比较了两个整数,结果存储在布尔值中。这是未简化的代码:
bool doLog = level >= debugLevel;
这是它崩溃的汇编代码:
cmp %ebx,0x14(%rbp)
// ebx = 3
// rbp = 0x6e696c7265
但是,当尝试打印存储在rbp中的地址值时,出现gdb错误:“无法访问地址0x6e696c7279处的内存”
让我感到烦恼的是,在打印debugLevel的地址时,我得到的地址将不同于存储在用于cmp的rbp寄存器中的地址:
p &debugLevel => 0x6e696c7279
i r rbp => 0x6e696c7265
答案 0 :(得分:0)
0x6e696c7265
类似于字母的ASCII码。您可能用字符串字节覆盖了指针。
(例如,缓冲区溢出可能踩到了保存的RBP值,然后在恢复RBP之后该函数返回到其调用者,当调用者尝试将RBP用作帧指针时中断了对本地的访问。实际上,{{1} }不会是帧指针,除非它可能在Windows上并且编译器会在返回地址上方的影子空间中分配该局部变量。)
打印debugLevel的地址,我得到的地址将不同于存储在用于cmp的rbp寄存器中的地址
GDB从调试信息中知道RBP+14
= RBP + 0x14。
这就是&debugLevel
指令使用位移为cmp
,特别是0x14
的寻址模式的原因。因此,从损坏的基址计算0x14(%rbp)
会给您另一个错误的地址。
&debugLevel
。这部分没有意思,也与您的内存损坏错误无关。