添加syslog为何能够阻止栈损坏(stack corruption)问题发生?
为什么添加syslog后栈损坏导致的崩溃消失,核心原因是syslog调用改变了程序的栈内存布局,刚好避开了原本会触发崩溃的非法内存覆盖逻辑,常见的场景通常是以下几种:
- 编译器优化行为改变
你的程序原本是优化编译版本,未加日志前,被打印的那个易损坏的变量可能被编译器优化存储在寄存器中,或是在栈上的排布刚好紧邻会产生越界写的内存区域(比如越界访问的数组末尾、野指针指向的栈地址),一旦被非法改写就会触发后续访问崩溃。
添加syslog打印该变量后,编译器需要遵循调用约定保证该变量可以被正常读取,会强制在栈上为它分配明确的内存空间,甚至会调整栈上各变量的排列顺序、额外插入栈填充字节对齐地址,原本会覆盖到关键变量或函数返回地址的溢出内容,现在只会覆盖到无意义的填充位或者syslog调用结束后就不再使用的临时内存,不会影响后续程序的正常执行。 - syslog栈帧的遮挡效果
调用syslog函数本身需要在当前栈顶开辟属于自己的栈帧空间,占用了原本会被溢出覆盖的内存区间,溢出的内容只会写入syslog自身使用的临时栈数据,syslog执行结束后这部分内存就会被回收丢弃,不会影响到业务逻辑用到的变量和返回地址。 - 变量地址偏移变化
你提到打印的变量恰好是原本会被破坏的变量,添加syslog之后栈整体向下偏移了固定大小,原本指向这个变量的非法写操作的地址,现在对应到了其他无意义的栈位置,不会再修改到这个变量的有效值,自然不会触发后续的非法内存访问崩溃。
内容的提问来源于stack exchange,提问作者Mouli
相关产品推荐
相关产品推荐

