STM32/GD32上内存堆栈溢出探测研究
无数次遭受堆栈溢出折磨,随着系统变得复杂,故障点越来越难以查找!
主要溢出情况如下:
1,一般RAM最后两块空间是堆Heap和栈Stack,堆从下往上用,栈从上往下用,任意一个用完,都会进入对方的空间
2,如果栈用完,进入堆的空间,这个时候系统是不会有任何异常的,也就是说,栈底没有什么意义。除非堆和栈指针重叠,否则大家相安无事,尽管栈用了堆的
3,如果栈用完进入堆,并且还碰到了堆的空间,这个时候系统仍然没有异常,但是堆栈会相互修改数据。最悲剧的就是栈里面保存的然会地址lr,一旦被堆指针修改,返回的时候就会跳到别的地址空间去了。绝大多数时候是这种情况,并且大多数跳到无效空间去。你应该感谢它跳到无效空间,让你马上发现错误。否则堆栈互相穿透而不报错,然后系统工作出现数据错乱,到时候看你想撞头还是想跳楼!
4,使用Keil的微库,malloc要用到堆空间,如果堆空间用完,再malloc的时候得到空指针,但是不会报错。然而,如果使用C++的new,这个时候会报错!
因为主线程和中断处理的存在,随时可能分配释放内存,这就导致了问题随时可能发生!非常难检查问题所在!
因此,SmartOS v2.5增加了内存堆栈溢出探测模块
声明:
#ifdef DEBUG void* operator new(uint size); void* operator new[](uint size); void operator delete(void * p); void operator delete [] (void * p); #endif
实现:
extern uint __heap_base; extern uint __heap_limit; void* operator new(uint size) { debug_printf(" new size: %d ", size); void * p = malloc(size); if(!p) debug_printf("malloc failed! size=%d ", size); else { debug_printf("0x%08x ", p); // 如果堆只剩下64字节,则报告失败,要求用户扩大堆空间以免不测 uint end = (uint)&__heap_limit; if((uint)p + size + 0x40 >= end) debug_printf(" + %d near HeapEnd=0x%08x", size, end); } assert_param(p); return p; } void* operator new[](uint size) { debug_printf(" new size[]: %d ", size); void * p = malloc(size); if(!p) debug_printf("malloc failed! size=%d ", size); else { debug_printf("0x%08x ", p); // 如果堆只剩下64字节,则报告失败,要求用户扩大堆空间以免不测 uint end = (uint)&__heap_limit; if((uint)p + size + 0x40 >= end) debug_printf(" + %d near HeapEnd=0x%08x", size, end); } assert_param(p); return p; } void operator delete(void * p) { debug_printf(" delete 0x%08x ", p); if(p) free(p); } void operator delete[](void * p) { debug_printf(" delete[] 0x%08x ", p); if(p) free(p); }
通过重载new/delete实现,并且带有64字节提前预测功能!在堆即将用完之前预警!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
我不相信神话,我只相信汗水!我不相信命运,我只相信双手!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2011-09-01 XCode中如何使用事务