我正在查看我正在GDB中调试的程序的以下反跟踪:
Thread 7 (Thread 3983):
#0 0xf7737430 in __kernel_vsyscall ()
#1 0x41b85412 in __lll_lock_wait () at ../nptl/sysdeps/unix/sysv/linux/i386/i486/lowlevellock.S:142
#2 0x41b80d6d in _L_lock_686 () from libpthread.so.0
#3 0xfbad8001 in ?? ()
#4 0x080eac80 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
我特别感兴趣的是0xfbad8001的帧地址及其含义。
平台是基于x86的,所以这个未对齐的地址是无效的。假设"bad"被编码成十六进制值,我猜这是一个神奇的数字,但到目前为止,我还不能确定是谁设置了这个值,或者为什么设置这个值。我试着在google和在线LXR数据库中搜索内核和glibc,但没有找到任何可以实际设置此值的代码行。
如果我用谷歌搜索"fbad8001",那么在回溯和内存转储中会有很多显示这个地址的点击。所以这个特殊的值似乎有一些意义,我假设它是一个来自某处的神奇数字,但到目前为止,我还没有找到设置它的代码。
谁设置这个值,它是什么意思?
内核是基于Linux 3.4.10, glibc是2.15。
除了内核和glibc源代码,我还搜索了gcc、gdb和binutils源代码,但仍然没有看到任何确凿的证据。
我对此的解释是,它是一个永远不会被看到的填充值,由一个或多个(未指定的)系统程序员非正式地选择,以适应特定的(未指定的)目的。
请注意以上地址也未对齐。这表明从堆栈中读取的所有内容都是可疑的。
我同意fbad8001可能是一个选择值,但不是一个非常重要的值。如果您想进一步研究,您需要使用合适的调试工具直接检查堆栈。您应该能够通过检查找到有效的堆栈帧(如果有的话),并且您可能会发现该值(或其他类似的非法值)的许多实例填充了不打算到达的堆栈部分。
如果这是一个调试版本,你可能会在堆栈帧之间发现像哨兵一样的值带。如果前一个堆栈帧被破坏,这个值可能会下降很长一段时间。你看了才知道。
如果你能找出是什么负责堆栈的特定区域,你将更好地知道谁问为什么这个值出现在那里。我猜沿着这条路走下去,你会学到很多,但收获很少。
我最近偶然发现了你的问题,当时我正在调试一个崩溃,其中发生了非常相同的可疑常量0xFBAD8001。
在我的例子中,有一个局部变量在它的函数作用域离开很久之后才被使用。然后,它被printf()函数的堆栈帧重写,当指针再次使用时,该结构包含0xFBAD8001的值。
这个神奇常数来自glibc,它被libio的_IO_FILE结构用作标志。
高阶的一半包含神奇的0xFBAD8000值,其余的用于标记。
这就是为什么很难用谷歌搜索