我目前正在尝试调试一个小型C程序,其一般结构如下所示:
int some_function(...) {
...
size_t buf_len = some_other_function(...)
...
}
main() {
...
int foo = some_function(...)
...
}
Run Code Online (Sandbox Code Playgroud)
我设置了一个断点some_function()
(使用lldb).但是,如果我在此断点处检查堆栈帧,它将显示buf_len
已存在的具有本地范围的变量,甚至具有任意(?)值.如果在此函数之前未在任何地方声明变量,这怎么可能?
ex *_*ilo 10
对于没有可变长度数组类型的此类对象,其生命周期从entry进入与其关联的块,直到该块的执行以任何方式结束.
因此,buf_len
当执行进入时,调试器中可见的情况应该不足为奇some_function()
.
在编译期间,每个变量都会添加到符号表中.因此,对变量的任何引用只有在已经声明并且插入到符号表中时才会解析.如果在声明之前引用变量,则会出现未定义引用的错误.
但对于所有的自动变量的空间被分配的所有功能于一个在功能序言中所述堆(即在IA32-64架构获得由所有自动变量所需的空间减去空间到堆栈指针寄存器中的堆栈帧).所需空间由编译器通过对该函数的符号表中存在的所有自动变量所需的存储空间求和来计算.
实际上,当在函数入口上创建堆栈帧时,所有自动变量都存在,即使在之后使用.
在某些情况下,如果编译器优化它们,则不分配变量,编译器优化代码选择使用变量抑制它的不同方式(即使用寄存器或简化流程并删除中间存储).