win32线程栈溢出问题 (二)
3.2、函数递归调用引发的栈溢出
写一段最简单的无穷递归代码,如下:
#include "stdafx.h"
void f(void)
{
f();
}
int _tmain(int argc, _TCHAR* argv[])
{
f();
return ;
}
在VS编译,Debug模式下运行之,结果报错
观察下调用栈,发现栈没有破坏,但被大量的f()调用沾满,如下:
这也充分说明了,是递归调用引起了栈溢出
转到汇编,在地址栏里输入上面错误框里的地址0x011515C9
可以看到,程序是在执行一次入栈操作时,报错了
我们转到Windbg运行程序,观察下
看下相关寄存器的值
栈顶指针esp=0x000a2f78
在看下线程栈下限
栈区界限下限为0x000A1000,然而,此时esp=0x000a2f78,已经非常接近下限了。0x000a2f78-0x000A1000=0x1f78<0x2000,也就是说,限制esp已经进入到栈区的后两个保护页了,当线程访问到倒数第三个页面的的时候,系统会为倒数第二个页面调拨物理存储器,此时还会抛出EXCEPTION_STACK_OVERFLOW。
针对函数递归调用而引起的栈溢出,我们可以采用下面的方式来解决:
- 给递归调用加上退出机制
- 改变设计,不用递归,比如可以用循环语句替代
3.3、栈里的某缓冲区溢出
这种情况比较复杂,不好模拟,当在线程里执行的某个函数里,开辟了某个缓冲区,对这个缓冲区进行写操作溢出,刚好覆盖了ESP或EBP值时,可能触发栈溢出异常。对这种栈缓冲区溢出问题,在编写代码时要吗非常小心索引值的检测,或则用安全版本的api来进行读写。
四、总结
前面的讲的两种情况,是平时工作中常遇到,也是非常好定位和修改的。这两种情况下,一般调用栈是不会发生破坏的,当我们看到最后调用的是_chkstk,那么通常是栈里使用了超大缓冲区,如果最后是停在了汇编指令push xx或则其他有入栈操作的指令时,且我们在调用栈里明显看到某函数的递归调用,那么这就是递归调用引发的栈溢出。第三种情况要具体问题具体分析了
win32线程栈溢出问题 (二)的更多相关文章
- win32线程栈溢出问题 (一)
一.什么是线程栈溢出 我们都知道,每一个win32线程都会开辟一个空间,用来临时存储线程执行时所调用的一系列函数的参数.返回地址和局部变量及其他上下文信息.这个空间就是线程的栈区.栈区的容量是有限的, ...
- win32线程
win32线程 一丶什么是线程 在windows中常听到的就是线程.多线程.啊什么的. 这里介绍一下什么是线程. 1.线程是附属在进程中的一个执行实体.简而言之就是执行代码的. 2.每个进程至少有一个 ...
- Android线程管理(二)——ActivityThread
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
- win32线程池代码(WinApi/C++)
win32线程池代码(WinApi/C++) 健壮, 高效,易用,易于扩, 可用于任何C++编译器 //说明, 这段代码我用了很久, 我删除了自动调整规模的代码(因为他还不成熟)/********** ...
- Win32线程——优先权
<Win32多线程程序设计>–Jim Beveridge & Robert Wiener Win32 优先权是以数值表现的,并以进程的“优先权类别(priority class)” ...
- juc线程池原理(二):ThreadPoolExecutor的成员变量介绍
概要 线程池的实现类是ThreadPoolExecutor类.本章,我们通过分析ThreadPoolExecutor类,来了解线程池的原理. ThreadPoolExecutor数据结构 Thread ...
- HDFS源码分析数据块复制监控线程ReplicationMonitor(二)
HDFS源码分析数据块复制监控线程ReplicationMonitor(二)
- Win32 线程同步
Win32 线程同步 ## Win32线程同步 ### 1. 原子锁 ### 2. 临界区 {全局变量} CRITICAL_SECTION CS = {0}; // 定义并初始化临界区结构体变量 {线 ...
- 线程池系列二:ThreadPoolExecutor讲解
一.简介 1)线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为: ThreadPoolExecutor(int corePoolSize, i ...
随机推荐
- c# webapi 过滤器token、sign认证、访问日志
1.token认证 服务端登录成功后分配token字符串.记录缓存服务器,可设置有效期 var token = Guid.NewGuid().ToString().Replace("-&qu ...
- SpringBoot--对SpirngMVC的自动配置
SpringBoot对SpringMVC提供了许多自动配置 Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver b ...
- c# 操作xml文件(读写)
根据项目需求,我们需要记录用户的操作痕迹,当用户下次登录操作同一个文件时,页面显示为用户上一次执行的用户轨迹,我们考虑把用户的历史记录写进xml文件中. 存储的xml数据结构: XML操作类: usi ...
- 创建Core项目使用IdentityServer4
本文主要参照https://www.bilibili.com/video/av42364337/?p=4 英文帮助文档:https://identityserver4.readthedocs.io/e ...
- VBA 字符串-相关函数(6-12)
Mid()函数 Mid()函数返回给定输入字符串中指定数量的字符. 语法 Mid(String,start[,Length]) 参数 String - 必需的参数.输入从中返回指定数量的字符的字符串. ...
- mysql 表关系 与 修改表结构
目录 mysql 表关系 与 修改表结构 两张表关系 分析步骤 修改表结构 mysql 表关系 与 修改表结构 两张表关系 多对一 以员工和部门举例 多个员工对应一个部门 foreign key 永远 ...
- flashdevelop调用ios方法
来源:http://blog.csdn.net/zu12jing/article/details/7331397 flash开发工具用的是flashdevelop(由于flashdevelop还能直接 ...
- 【HCIA Gauss】学习汇总-数据库管理(数据库基本概念)-3
数据库:操作系统文件或磁盘数据块的集合数据库实例: 指操作系统中一系列进程以及为这些进程分配的内存块 通常来说一个数据库实例对应着一个数据库[数据库实例是访问数据的通道] 多实例:利用多实例 可以充分 ...
- homebrew一直处于updating状态
vim ~/.bash_profile 增加一行 export HOMEBREW_NO_AUTO_UPDATE=true 之后再source一下
- 通过visual studio制作类库的文档
java的集成开发工具,可以导出jar的文档. visual studio 也可以生成类库的文档,邮件项目属性,生成,输出下,选择XML文档文件.然后生成项目,就会再bin下面生成一个xml文件. 将 ...