gcc堆栈优化
您好,我有一个关于 gcc(或 g++)可能的堆栈优化的问题。FreeBSD
下的示例代码(UNIX 差异在这里重要吗?):
void main() {
char bing[100];
..
string buffer = ....;
..
}
我在 gdb 中发现该程序的核心转储是地址 bing 的值实际上低于该缓冲区(即 &bing[0] < &buffer)。
我认为这与教科书上所说的完全相反。那里可以吗 是一些编译器优化,以这样的方式重新组织堆栈布局 方式?
这似乎是唯一可能的解释,但我不确定。
如果您感兴趣,核心转储是由于缓冲区溢出造成的 bing 到缓冲区(但这也证实了 &bing[0] < &buffer)。
谢谢!
Hi I have a question on possible stack optimization by gcc (or g++)..
Sample code under FreeBSD (does UNIX variance matter here?):
void main() {
char bing[100];
..
string buffer = ....;
..
}
What I found in gdb for a coredump of this program is that the address
of bing is actually lower than that buffer (namely, &bing[0] < &buffer).
I think this is totally the contrary of was told in textbook. Could there
be some compiler optimization that re-organize the stack layout in such a
way?
This seems to be only possible explanation but I'm not sure..
In case you're interested, the coredump is due to the buffer overflow by
bing to buffer (but that also confirms &bing[0] < &buffer).
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编译器可以按照自己希望的方式自由组织堆栈帧(假设它们甚至使用堆栈)。
他们这样做可能是出于对齐原因,或者是出于性能原因,或者根本没有任何原因。假设任何特定的顺序是不明智的。
如果您没有通过溢出缓冲区来调用未定义的行为,您可能永远不会知道,而事情应该如此。
编译器不仅可以重新组织变量,如果可以确定变量未被使用,还可以优化它们以消除它们的存在。使用代码:
比较正常的汇编器输出:
与疯狂优化的:
注意到后者缺少什么吗?是的,没有堆栈操作可以为
bing
或x
创建空间。它们不存在。事实上,整个代码序列可以归结为:Compilers are free to organise stack frames (assuming they even use stacks) any way they wish.
They may do it for alignment reasons, or for performance reasons, or for no reason at all. You would be unwise to assume any specific order.
If you hadn't invoked undefined behavior by overflowing the buffer, you probably never would have known, and that's the way it should be.
A compiler can not only re-organise your variables, it can optimise them out of existence if it can establish they're not used. With the code:
Compare the normal assembler output:
with the insanely optimised:
Notice anything missing from the latter? Yes, there are no stack manipulations to create space for either
bing
orx
. They don't exist. In fact, the entire code sequence boils down to:编译器可以自由地在堆栈上布局局部变量(或将它们保留在寄存器中或对它们执行其他操作),但它认为合适:C 和 C++ 语言标准没有说明这些实现细节,POSIX 或UNIX。我怀疑你的教科书是否另有说明,如果是的话,我会寻找一本新教科书。
A compiler is free to layout local variables on the stack (or keep them in register or do something else with them) however it sees fit: the C and C++ language standards don't say anything about these implementation details, and neither does POSIX or UNIX. I doubt that your textbook told you otherwise, and if it did, I would look for a new textbook.