解决递归调用栈溢出的方法是通过尾递归优化,事实上尾递归和循环的效果是一样的,所以,把循环看成是一种特殊的尾递归函数也是可以的。
尾递归,在函数返回的时候,调用自身本身,并且,return语句不能包含表达式。这样,编译器或者解释器就可以把尾递归做优化,使递归本身无论调用多少次,都只占用一个栈帧,不会出现栈溢出的情况。
扩展资料
针对堆栈溢出可能造成的计算机安全问题,通常有以下这些防范措施:
1、强制按照正确的规则写代码。
2、通过 *** 作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码。但由于攻击者并不一定要通过植入代码来实现攻击,同时linux在信号传递和GCC的在线重用都使用了可执行堆栈的属性,因此该方法依然有一定弱点。
3、利用编译器的边界检查来实现缓冲区的保护。该方法使得缓冲区溢出不可能出现,完全消除了缓冲区溢出的威胁,但代价较大,如性能速度变慢。
4、程序指针完整性检查,该方法能阻止绝大多数缓冲区溢出攻击。该方法就是说在程序使用指针之前,检查指针的内容是否发生了变化。
参考资料来源:百度百科-堆栈溢出
参考资料来源:百度百科-栈溢出
什么时候可能出现内核崩溃,kernrl panic呢?
Linux在中断处理程序中,它不处于任何一个进程上下文,如果使用可能睡眠的函数,则系统调度会被破坏,导致kernel panic。因此,在中断处理程序中,是不能使用有可能导致睡眠的函数(例如信号量等)。
在中断发起的软中断中,其上下文环境有可能是中断上下文,同理,也不能调用可能导致睡眠的函数。软中断执行时,全局中断是打开的,而中断程序执行时,全局中断是禁止的。
软中断除了系统调度进入点,当软中断数量频繁时,内核中有一个专门的软中断的后台程序daemon来处理其事务。
还有内核堆栈溢出,或者指针异常访问时,也会出现kernel panic。
堆栈溢出:程序循环或者多层嵌套的深度过多时,可能会导致栈溢出。
显而易见,除0异常、内存访问越界、缓冲区溢出等错误时,当这些事件发生在应用程序时,Linux内核的异常处理机制可以对这些由应用程序引起的情况予以处理。当应用程序出现不可恢复性错误时,Linux内核可以仅仅终止产生错误的应用程序,而不影响其他程序。如果上述 *** 作发生在内核空间,就会引起kernel panic。
还有内核陷入死锁状态,自旋锁嵌套、在内核线程中,存在死循环的 *** 作等等都会引起kermel panic。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)