项目经验之谈--栈溢出

前言
在嵌入式领域,我们编码调试时,经常会出现段错误 (core dumped),根据个人经验,最常见的莫过于“空指针”、“野指针”内存泄露(一般是堆区泄露)、栈溢出、越界访问等。
笔者在此只阐述栈溢出(栈区被破坏)的情况,因为这种问题在项目中极具有典型性、隐藏性、且不易被跟踪发现。
栈破坏的具体表现为:在该函数(栈帧内)执行时,不会立即崩溃(Segmentation fault)。而是函数执行完后返回时,返回地址等栈保存的信息被破坏。才出现崩溃。

项目需求
该项目是需要”通过GSM模块的GPRS功能来实现上网功能,需要跑少量流量,模拟人为的上网功能。防止被运营商封杀”主要应用于VOIP语言网关产品当中。正是因为有这样的需求,才有了现有BUG的出现。
技术上来说,主要是通过配置web前端的URL地址,后台随机产生前端配置的URL,通过下发到GSM模块,GSM模块再发给运营商。这样实现了一个数据流量的交互。下图为web配置。
web前端配置URL
前端定义的URL最大长度为128字节。
URL长度
我们再来看后端发送代码。
后台发送代码
从上述可以看出at_cmd_buffer就是我们需要发送给GSM模块的缓存buffer。再来看看其定义的大小(64字节)
缓存区大小
缓存区大小是64字节,而URL最大是128字节,外加AT指令的长度肯定超过了128字节

程序崩溃
GDB调试,函数调用栈已经被完全破坏了。
程序崩溃
打印显示at_cmd_buffer缓存区已经出现错误。

原因分析
程序员在找BUG时,最好是能够深层次去理解其中的机理,这样有助于经验的积累,也是一笔宝贵的财富。既然是栈溢出,那么我就得来从函数调用栈来分析。
为了更好的理解,我们必须有程序堆、栈、段等概念。
函数调用都有自己的一个栈帧。

安全编程
很多人在编程的时候随手拈来调用一些系统库函数(C库),尤其在字符串操作时候,边界问题是一直需要我们注意的。以下有两种不同的写法。
int sprintf( char *buffer, const char *format,… ); <不安全>
int snprintf(char *str, size_t size, const char *format, …) <安全>

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值