如何确定线程栈的基址?

news2024/11/17 5:32:50

很早之前,我遇到过几个与栈相关的问题,当时总结过几篇关于线程栈的文章,分别是 《栈大小可以怎么改?》、《栈局部变量优化探究,意外发现了 vs 的一个 bug ?》、《栈又溢出了》、《有趣的异常》。在这几篇总结中,简单的总结了栈溢出的原因,设置线程栈大小的方法。但是还有一点没弄清楚:操作系统是怎么知道一个线程的栈大小的?一定记录在某个位置了,否则就不能正确的在栈溢出的时候抛出异常了。不能根据 PE 头中的字段判断,因为在创建线程的时候可以指定线程栈大小。TEB 中的 StackLimit 是真正的栈底吗?带着这些疑问一起来刨根问底吧~

友情提示:结论在文章末尾。

!teb 命令

相信,很多小伙伴儿都知道,可以使用 !teb 查看线程相关的信息。

 

其中的 StackBaseStackLimit 分别指示了栈顶和当前栈使用情况。因为栈是从上向下增长的,所以 StackBase 的值比较大。

我之前一直认为这两个字段分别指向了栈顶和栈底(线程栈可以到达的最低位置),可以通过这两个字段计算出线程栈大小。后来才发现 StackLimit 并没有指向栈底,而是指向了线程栈当前所到达的最低位置。

线程栈默认的大小是 1MB。如果计算一下 StackBase - StackLimit 的值即可知道,它们的差值是 256KB,而不是 1MB

那么当前线程栈的大小是不是 1MB 呢?该如何确认呢?可以通过 vmmap 确定。

vmmap

打开 vmmap.exe,并选择想要查看的进程,即可进行查看。

注意: 当选择的进程已经中断到调试器时,vmmap.exe 会一直等待,需要让目标进程运行起来。

 

可以看到,线程 9804 的线程栈大小确实是 1MB

根据以上信息,可以确定 StackLimit 并不是真正的线程栈栈底。那么,栈底位置到底记录在哪里了呢?

最近在重翻《软件调试》的时候,发现了一个关键函数。

栈空间自动增长的关键函数

在第 2222.8.1 节 栈空间的自动增长(P617)中提到了一个关键函数 MiCheckForUserStackOverflow。该函数是判断栈空间能否增长的关键函数。如果知道该函数是如何实现的,就能找到栈底了。

脑子里很快有了三个选项:google 搜索,ReactOSserver03 源码。正好电脑上有源码,不用考虑其它两个选项了。

参考源码

知道了函数名,但是还不知道这个函数在哪个文件中实现的。这个简单,在 File Locator 中输入 MiCheckForUserStackOverflow,很快就找到了关键的文件。

 

双击打开 accesschk.c,找到 MiCheckForUserStackOverflow。注释很清晰的解释了这个函数的作用。 

 

说明: 该函数的实现在 wrk 中也可以找到,地址是 https://github.com/mic101/windows/blob/master/WRK-v1.2/base/ntos/mm/acceschk.c。

整个函数虽然行数很多,但是有大部分是注释,而且考虑了各种情况。我截取了最关键的部分,如下图:

 

看样子 teb->DeallocationStack 记录了栈底。 StackBase 减去 teb->DeallocationStack 的值应该是栈大小(默认是 1MB)。在 windbg 中验证一下。

验证

windbg 中输入如下命令 dt _teb 0043f000 -y DeallocationStack -y NtTib.StackBase,只查看 DeallocationStackNtTib.StackBase 的值。然后计算差值,发现正好是 1MB0x100000)。

总结

  • _TEB 结构体的 DeallocationStack 指向线程栈底,而 NtTib.StackLimit 指向的是线程栈当前所到达的最低位置。

  • 可以在 dt 命令中通过 -y 选项来显示特定字段。

  • vmmap.exe 可以非常详细的展示进程虚拟内存情况。

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1200720.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【fast2021论文导读】 Learning Cache Replacement with Cacheus

文章:Learning Cache Replacement with Cacheus 导读摘要: 机器学习的最新进展为解决计算系统中的经典问题开辟了新的、有吸引力的方法。对于存储系统,缓存替换是一个这样的问题,因为它对性能有巨大的影响。 本文第一个贡献,确定了与缓存相关的特征,特别是,四种工作负载…

C++基础(2)——类和对象

目录 1. 类的引入: 2. 类的定义: 2.1类的定义以及基本结构: 2.2 类的访问限定符: 3. 类的声明与定义的分离: 4. 类的实例化: 5. 类的大小计算: 1. 类的引入: 在数据结构系列的…

有源RS低通滤波

常用的滤波电路有无源滤波和有源滤波两大类。若滤波电路元件仅由无源元件(电阻、电容、电感)组成,则称为无源滤波电路。无源滤波的主要形式有电容滤波、电感滤波和复式滤波(包括倒L型、LC滤波、LCπ型滤波和RCπ型滤波等)。若滤波电路不仅有无…

【vue+el-upload+vue-cropper】vue图片上传,vue-cropper图片裁剪后上传

一. 先看效果演示 二. 图片上传 用的el-upload加el-image组件 html部分 <el-dialog> ...//无关代码已省略<div v-for"item in imgArr" :key"item.index"><span>{{ item.name }}</span><el-upload action"#" list-t…

【408】计算机学科专业基础 - 数据结构

数据结构知识 绪论 数据结构在学什么 如何用程序代码把现实世界的问题信息化 如何用计算机高效地处理这些信息从而创造价值 数据结构的基本概念 什么是数据&#xff1a; 数据是信息的载体&#xff0c;是描述客观事物属性的数、字符及所有能输入到计算机中并被计算机程序…

K8S知识点(十)

&#xff08;1&#xff09;Pod详解-启动命令 创建Pod&#xff0c;里面的两个容器都正常运行 &#xff08;2&#xff09;Pod详解-环境变量 &#xff08;3&#xff09;Pod详解-端口设置 &#xff08;4&#xff09;Pod详解-资源配额 修改&#xff1a;memory 不满足条件是不能正常…

揭秘:车企如何利用5R模式在数位行销领域取得突破

01 车企进入“大逃杀”时间 汽车行业一边是出口“捷报频传”&#xff0c;一边是内销“压力山大”。 内销的难&#xff0c;在之前中部某省的政府“骨折价”补贴掀起的“价格战”中已经可见一斑。这一颇具标志性的事件反映了汽车行业&#xff0c;尤其是燃油车行业正处在巨大的转…

曾被揭露造假的越南,再次宣称研发成功5G芯片,这是真的么?

日前在2023 年越南国际创新展 (VIIE 2023) 上&#xff0c;越南的Viettel宣布成功研发5G芯片&#xff0c;可以应用于5G基站&#xff0c;并表示该公司已成为全球第六大芯片设备供应商。 越南是近10年来制造业发展强劲的国家之一&#xff0c;甚至还在2022年成为全球经济增长最快的…

C#多线程入门概念及技巧

C#多线程入门概念及技巧 一、什么是线程1.1线程的概念1.2为什么要多线程1.3线程池1.4线程安全1.4.1同步机制1.4.2原子操作 1.5线程安全示例1.5.1示例一1.5.2示例二 1.6C#一些自带的方法实现并行1.6.1 Parallel——For、ForEach、Invoke1.6.1 PLINQ——AsParallel、AsSequential…

TSINGSEE视频智能分析人员入侵AI检测算法如何让城市管理更加高效、智慧?

在城市管理场景中&#xff0c;经常面临着禁区垂钓、非法捕捞、行人闯红灯、小区盗窃、车辆乱停乱放等一系列管理难题&#xff0c;这给城市发展带来了不小的阻力&#xff0c;同时也极易增加管理的人力、物力和财力。传统的人员巡逻监管效率低并且存在时间差&#xff0c;很难及时…

2.4.0 Milky Way 强势登场!新功能大爆炸,让你High翻全场!

Yo开发达人们&#xff0c;我们有重磅新功能要给你们放送啦&#xff01; Check it out 数据汇总不再单调&#xff0c;新的聚合函数登场&#xff01; compact_state_agg #1359gauge_agg #1370first #1395last #1413mode #1440increase #1476delta #1395time_delta #1405rate #14…

内存映射:PS和PL DDR3的一些区别

之前写的一些资料&#xff1a; PS与PL互联与SCU以及PG082-CSDN博客 参考别人的资料&#xff1a; PL读写PS端DDR的设计_pl读写ps端ddr数据-CSDN博客 xilinx sdk、vitis查看地址_vitis如何查看microblazed地址_yang_wei_bk的博客-CSDN博客 可见&#xff0c;PS端的DDR3需要从…

从0到1实现一个前端监控系统(附源码)

目录 一、从0开始 二、上报数据方法 三、上报时机 四、性能数据收集上报 收集上报FP 收集上报FCP 收集上报LCP 收集上报DOMContentLoaded 收集上报onload数据 收集上报资源加载时间 收集上报接口请求时间 五、错误数据收集上报 收集上报资源加载错误 收集上报js错…

msvcp120.dll丢失的6种解决方法,教你如何修复dll文件丢失

“找不到msvcp120dll,无法继续执行代码的6个修复方案”。我相信很多朋友在运行某些程序时&#xff0c;可能会遇到这样的错误提示&#xff1a;“找不到msvcp120dll&#xff0c;无法继续执行代码”。那么&#xff0c;msvcp120dll究竟是什么&#xff1f;为什么会丢失呢&#xff1f…

Java基础知识第四讲:Java 基础 - 深入理解泛型机制

Java 基础 - 深入理解泛型机制 背景&#xff1a;Java泛型这个特性是从JDK 1.5才开始加入的&#xff0c;为了兼容之前的版本&#xff0c;Java泛型的实现采取了“伪泛型”的策略&#xff0c;即Java在语法上支持泛型&#xff0c;但是在编译阶段会进行所谓的“类型擦除”&#xff0…

NestJS——基于Node.js 服务器端应用程序的开发框架

文章目录 前言什么是 NestJS&#xff1f; 一、NestJS特性&#xff1f;二、使用步骤Typescript 知识后端开发基本知识新建项目目录结构 前言 Nestjs中文文档 什么是 NestJS&#xff1f; Nest (NestJS) 是一个用于构建高效、可扩展的 Node.js 服务器端应用程序的开发框架。它利用…

【JVM系列】- 寻觅·方法区的内容

寻觅方法区的内容 &#x1f604;生命不息&#xff0c;写作不止 &#x1f525; 继续踏上学习之路&#xff0c;学之分享笔记 &#x1f44a; 总有一天我也能像各位大佬一样 &#x1f31d;分享学习心得&#xff0c;欢迎指正&#xff0c;大家一起学习成长&#xff01; 文章目录 寻觅…

杂记 | 使用FRP搭建内网穿透服务(新版toml配置文件,搭配反向代理食用)

文章目录 01 需求与回顾02 下载程序包03 编辑.toml文件3.1 编辑frps.toml3.2 编辑frpc.toml 04 启动服务4.1 启动服务端4.2 启动客户端 05 配置反向代理&#xff08;可选&#xff09;06 windows设置为默认启动&#xff08;可选&#xff09;6.1 创建启动脚本6.2 设置为开机自启 …

【Spring Cloud】声明性REST客户端:Feign

Spring Cloud Feign ——fallback 服务降级 1. Feign 简介2. Feign 的基础使用2.1 普通 HTTP 请求2.2 Feign 远程调用上传文件接口 1. Feign 简介 Feign 是一个声明式的 HTTP 客户端&#xff0c;它简化了编写基于 REST 的服务间通信代码的过程。在 Spring Cloud 中&#xff0c…

你一定要学会的Java语法 -- 【继承】

书接上回&#xff0c;我们已经学完了类和对象&#xff0c;今天内容可能有一点难&#xff0c;相信自己能跨过这道坎。 目录 一. 继承 1.什么是继承 2. 继承的概念 3. 继承的语法 4.父类成员访问 子类和父类成员变量同名 子类和父类成员方法同名 5.super关键字 6.子类构…