软件调试笔记30 - 栈和函数调用 : 栈简介

x86 函数调用过程及栈帧 在调试崩溃时候,或者在调用栈不正确的时候就需要手动的推动调用栈,需要知道函数是如何调用的,今天就来看一下栈帧。 函数调用时候会做什么 我们知道在函数调用时候,很多临时变量是保存到栈上,等到需要时候在取出来,栈的特点是后进先出。这一点非常适合函数的调用关系,例如:在多级的函数调用时候,最后调用的函数的内容使用完就可以释放掉,然后交给上层函数处理就可以了。 接下来,我们看一下在函数调用过程中,有哪些操作,如何通过栈来保存数据的。 用简单的示例演示调用过程,main中调用了func函数。其中cout的作用 阅读详情

简介:

从数据结构,栈是一种用来存储数据的容器,遵从后入先出规则。 编译器在编译时会将函数调用和局部变量存取编译为合适的栈操作。操作系统在创建线程时,会为每个线程创建栈,包括分配栈所需的内存空间和初始化有关的数据结构及寄存器。以x86为例,SS(stack segment)寄存器用来描述栈所在的内存段,ESP(extended stack pointer)寄存器用来记录栈的栈顶地址。CPU在执行程序时,会假定SS和ESP已经指向一个设置好的栈,执行PUSH指令就向ESP所指向的内存地址写入数据,然后调整ESP值,使其指向新的栈顶。执行POP就弹出数据,并调整ESP的值。当CPU执行CALL和RET这样的函数调用指令时,也会使用栈。


从线程角度,栈是每个WINDOWS线程必备的设施。每个线程至少有一个栈,系统线程之外的每个线程有两个栈,一个供该线程在用户态在执行使用-用户态栈,一个在内核态下执行使用,称为内核态栈。在一个多任务的系统中,会有多个线程,所以有很多个栈存在。但对CPU而言,它只使用当前栈,即SS和ESP所指向的栈。当在不同任务切换,以及同一个任务内核态和用户态切换,系统会保证SS和ESP始终指向合适的栈。


用户态栈和内核态栈:






WINDOWS会为系统内的普通线程建立一个共享的TSS段,当进行软件方式的任务切换时,WINDOWS会把当前任务的内核态信息复制到TSS段。


用户态栈的信息记录在线程信息块_NT_TIB结构中,它是线程环境块TEB结构的第一部分,因此可以根据TEB地址来显示它。



从功能和使用方式看,用户态栈和内核态栈是相同的。但因为服务对象不同,所以还是有差异的。

1. 首先, 用户态栈是分配在所在线程的用户空间中,而内核态栈是系统空间。而用户空间是共享的,系统空间是全局的。一个系统内用户空间有很多个,但系统空间只有一个。

2. 用户态栈是可指定大小的,默认是1MB,而内核态栈是系统来控制大小的,大小因处理器结构不同而不同,但通常在十几KB到几十KB之间。在一个线程被转变为GUI线程后(创建的时候,所有线程都是非GUI线程),WINDOWS会为他创建一个较大的可增长的内核态栈来替换掉原来的栈,称为大内核态栈。

ARM64栈帧回溯:从FP与LR寄存器解析函数调用链 本文深入解析ARM64架构中栈帧回溯的核心原理,重点探讨帧指针(FP)与链接寄存器(LR)在函数调用链中的关键作用。通过实际代码示例和GDB调试技巧,详细展示如何利用FP和LR寄存器解析函数调用关系,并提供异常情况处理指南与性能优化建议,帮助开发者高效进行ARM64平台调试。 阅读详情

相关推荐

ARM64栈帧探秘:从寄存器到函数调用的微观世界

本文深入解析ARM64架构的栈帧机制,从寄存器体系到函数调用的全流程,揭示FP(帧指针)和LR(链接寄存器)在栈帧构建中的关键作用。通过具体示例和调试技巧,帮助开发者掌握ARM64栈帧的底层原理,提升调试和性能优化能力。

weixin_29230649的博客 281

linux程序内存布局、线程栈、函数栈

1.linux内存布局 原文链接:https://blog.youkuaiyun.com/yangkuanqaz85988/article/details/52403726 Linux 对进程地址空间有个标准布局,地址空间中由各个不同的内存段组成 (Memory Segment),主要的内存段如下: 程序段 (Text Segment):代码 数据段 (Data Segment):已初始化全局变量或者静态变量 BSS段 (BSS Segment):未初始化的全局变量或者静态变量 堆区 (Heap) : 存储动态内存分

sun77的博客 712

iOS逆向实战:用ARM64汇编破解一个简单的函数调用栈

本文通过一个简单的加法函数实例,详细解析了iOS应用在ARM64架构下的函数调用栈机制。从环境准备、寄存器使用到栈帧布局,逐步展示如何逆向分析ARM64汇编代码,并提供了实用的调试技巧和常见问题解决方案,帮助开发者深入理解iOS底层运行原理。

weixin_27038245的博客 561

函数调用栈从何而来

程序员对函数调用栈是再熟悉不过了,无论是使用IDE调试还是GDB等工具进行调试,都离不开函数调用栈的分析。当我们遇到卡顿问题的时候,经常苦于没有卡顿现场,也就是函数调用栈进行分析解决。除了利用上述工具获取函数调用栈,能不能想办法在代码中记录函数调用栈,特别是卡顿的时候,还好是有办法的~

记录点滴,终成江河! 1196

aarch64栈帧结构解析:函数调用约定深度剖析

深入剖析aarch64架构下的栈帧布局和函数调用机制,揭示寄存器使用规则与参数传递方式,帮助开发者理解底层执行流程,优化程序性能。聚焦aarch64调用约定细节,结合实际场景解析栈管理策略。

weixin_30299319的博客 426

ARM Cortex-M3函数调用时,你的局部变量到底藏在哪?一个调试实战带你摸清栈帧

本文深入解析ARM Cortex-M3函数调用时的栈帧机制,通过调试实战展示局部变量在栈中的存储位置。结合Keil MDK环境下的STM32F103开发板实验,详细讲解AAPCS调用标准、寄存器使用及栈内存布局,帮助开发者理解底层运行原理并解决栈溢出等常见问题。

weixin_30666401的博客 476

ARM64函数调用标准与栈帧实战:从寄存器传参到栈帧回溯

本文深入解析ARM64架构下的函数调用标准与栈帧机制,重点介绍寄存器传参规则(x0-x7传递前8个参数)、关键寄存器分工及栈帧构建原理。通过GDB调试实战演示栈帧回溯技巧,帮助开发者掌握ARM64底层调试与性能优化方法,提升代码稳定性和执行效率。

yhn456789的博客 858

iOS逆向之深入解析函数本质·函数调用栈与相关指令

一、栈与寄存器 ① 栈 栈:是一种具有特殊的访问方式的存储空间(即先进后出 Last In First Out, LIFO): 高地址往低地址存数据(存:高–>低); 栈空间开辟:往低地址开辟(开辟:高–>低)。 ② SP 和 FP 寄存器 SP 寄存器:在任意时刻会保存栈顶的地址; FP 寄存器(也称为 x29 寄存器):属于通用寄存器,但是在某些时刻(例如函数嵌套调用时)可以利用它保存栈底的地址; arm64 开始,取消了 32 位的 LDM、STM、PUSH、POP 指令,取而

╰つ栺尖篴夢ゞ 1万+

C++调试:函数调用过程和堆栈

最后两条指令是函数结尾处的序曲,通常称作函数的 epilogue(尾声),它们的主要作用是恢复函数开始时保存的状态,并释放栈空间,以便函数可以正确地返回到调用者。

luyoung0001@gmail.com的博客 1314

Linux下自动化解析q7签名文件的有效期与时间戳

本文详细介绍了在Linux环境下自动化解析q7签名文件有效期与时间戳的方法。通过编写高效脚本,开发者可以批量提取签名时间信息,验证签名有效性,并集成到CI/CD流程中。文章提供了完整的脚本实现,包括错误处理、批量处理功能,并解决了常见环境问题,特别适用于国产操作系统如UOS的开发场景。

weixin_30872499的博客 518

西门子S7-1200与汇川SV660F伺服Profinet通讯调试实战

在工业自动化领域,Profinet作为工业以太网标准协议,凭借其高实时性和灵活组网能力,已成为伺服驱动器与PLC通讯的主流选择。其核心原理是通过设备名识别、IP分配以及标准报文(如111速度报文、105定位报文)传输控制字与状态字,实现驱动器的精准控制。相比传统脉冲或CANOpen方案,Profinet直连省去了协议转换网关,降低了成本与故障点,尤其适用于绕线设备、包装机械等中小型单轴或多轴运动控制系统。本文以西门子S7-1200 PLC搭配汇川SV660F伺服为例,完整梳理了从GSDMD组态、InoDri

weixin_29184371的博客 222

ARM64基础 -- x29 和 x30 寄存器详解

x29(FP):用于指向当前栈帧的基址,便于函数内部访问局部变量和参数,帮助调试和栈回溯。x30(LR):用于存储函数的返回地址,确保函数执行完毕后能正确返回调用者。通过这些寄存器,ARM64 能够高效管理函数调用和返回,保持程序的结构清晰和可维护性。

sz66cm 学习随笔 4317

软件测试--用例篇(测试用例的好处、测试用例的七种设计方法、测试用例的粒度、测试用例的评价)

作为软件测试工程师,最主要的工作就是:编写测试用例,那么为什么要编写测试用例?它有什么好处?如何编写测试用例?测试用例写简单好还是复杂好?如何评价测试用例的质量? 天呐撸!能说不会吗?! 作为倾向软件测试工程师的老铁们,还是一起来学习吧! 一、编写测试用例的好处 测试用例是测试者的依据 测试用例使得工作可重复,是自动化测试的基础 补充:自动化测试的前提条件是:功能比较稳定,页面...

cherrydreamsover的博客 3734

函数调用栈帧分析

分析栈帧的调用过程,需要一些工具和汇编知识的学习。首先简单的介绍一下分析栈帧时必用的一些汇编指令。 工具 VS2013调用堆栈窗口查看工具,反汇编窗口工具,监视窗口工具,内存窗口查看工具 汇编命令 mov指令:例:mov ax bx 表示把bx寄存器的值赋值给ax寄存器。 push指令:例:push ax 表示将寄存器ax中的数据送入栈中。 pop指令 :例:pop ax

better1914的博客 795

京东运维面试题及参考答案

cgroup(Control Group)是 Linux 内核提供的一种可以限制、控制与分离一个进程组群的资源(如 CPU、内存、磁盘 I/O 等)的机制。通过 cgroup,可以为不同的进程或进程组分配特定的资源配额,实现资源的隔离和管理。比如,在一个服务器上运行多个容器时,可以使用 cgroup 来限制每个容器对 CPU 和内存的使用,防止某个容器占用过多资源而影响其他容器的运行。cgroup 还可以对进程进行优先级设置,确保关键进程能够优先获得资源。

大模型大数据攻城狮的专栏 1235

一个人干完整个运营团队!浙大开源「Easel」全链路拆解:从热点发现到自动发布,一个 Agent 直接做出来

一个人干完整个运营团队?浙大 REAL 实验室开源的 Easel,把 OpenClaw Agent、账号画像、114 个内容技能和真实媒体工具接在一起:从热点发现、选题策划、图文视频创作,到七平台适配发布、数据归因复盘,全链路一个 Agent 闭环完成,产物按项目归档。本文完整拆解其五层工作流、四层 Prompt Stack 架构、画像内联机制、Skill 三层加载与产物契约,附安装部署、.env 关键配置、Embedding 避坑、已知问题修复等实战干货,全程无虚构、可复现。

program哲学 282

x86函数调用栈分析

2)、add6函数栈的返回函数的地址替换为hack的地址。1)、查找add6函数栈的返回函数的地址。

gwtak的博客 384

IEC61850规约客户端软件开发实战(第六章)

IEC 61850标准中的GOOSE(Generic Object Oriented Substation Event,面向通用对象的变电站事件)功能是变电站自动化系统的核心通信机制,主要用于实现智能电子设备(IED)间高可靠性、低延时的实时信号传输。本章简述其核心功能与技术特点。

半青年的博客 1777

Linux打印内核函数调用栈(dump_stack)

在Linux内核中提供了一个可以打印出内核调用堆栈的函数 dump_stack() 该函数在我们调试内核的过程中可以打印出函数调用关系,该函数可以帮助我们进行内核调试,以及让我们了解内核的调用关系。 该函数头文件为: #include <asm/ptrace.h> 使用方式: 直接在想要查看的函数中添加 dump_stack(); 案例: 随便写了一个模块test....

SweeNeil 1万+

基于STM32的嵌入式平台实现EtherCAT主站

本文将介绍如何在基于STM32的嵌入式平台上构建EtherCAT主站,并提供相应的源代码。使用SOEM库提供的API函数,我们可以实现与EtherCAT从站设备的实时通信和数据交换。在STM32的代码中,使用SOEM库提供的API函数初始化EtherCAT主站。在SOEM库中,我们可以找到EtherCAT主站的实现代码和相关的API函数。使用SOEM库提供的API函数实现EtherCAT主站的功能,包括发送和接收EtherCAT数据帧、处理从站设备的状态等。确保连接正常并且设备能够相互通信。

CodeSageX的博客 2832

MICCAI‘23 | TSegFormer:基于几何引导Transformer的口内扫描3D牙齿分割

光学口内扫描仪(IOS)在数字牙科中广泛应用于提供牙冠和牙龈的详细3D信息。准确的3D牙齿分割对于各种牙科应用至关重要,但现有方法在复杂边界处容易出错,并且在不同患者之间表现不佳。本文提出了TSegFormer,它通过多任务3D Transformer架构捕捉IOS点云中不同牙齿和牙龈之间的局部和全局依赖关系。此外,作者设计了一种基于新颖点曲率的几何引导损失,以端到端方式优化边界,避免了耗时的后处理,从而实现临床适用的分割。

小白学视觉 289

linux中Oops信息的调试及栈回溯—Linux人都知道,这是好东西!

============================================================================= 原文地址:http://blog.micro-studios.com/?p=615#comment-1069 看后感想:這点比 ldd3上讲的都仔细 2012年11月29日11:24:17:有BUG_ON就不用反汇编了。。。

Android/Linux的专栏 5万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

ARM64架构栈帧回溯

ARM64架构栈帧回溯简介以及demo演示

小立仔 3151

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

蓝德调试软件及固件em30-em300资源下载

蓝德调试软件及固件em30-em300资源下载 【下载地址】蓝德调试软件及固件em30-em300资源下载 本资源仓库提供蓝德调试软件及固件em30-em300系列下载,帮助用户轻松配置、调试和升级设备。包含详细的使用说明和注意事项,确保操作简单且安全。通过该软件,您可以优化设备性能,保持其稳定运行。无论是初次使用还是经...

gitblog_06776的博客 723

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

通过编程方式获取backtrace(函数调用栈)(接上篇core dump调试解释)

在用GDB调试器时可以查看所谓的Backtrace,它包含一系列的函数调用信息,用命令backtrace或bt可以在GDB中查看函数调用栈的信 息。有些场合没法使用GDB时,则可以用glibc库函数中的一些相关函数来得到backtrace的信息(在头文件execinfo.h中):

我们一直在努力 2493

从汇编层看64位程序运行——函数的调用和栈平衡

不知道有没有人想过一个问题:A函数调用B函数,B函数是如何知道在调用结束后回到A函数中的?比如下面的代码,main函数调用foo。当foo执行完毕,需要执行main函数的return 0语句。但是main和foo是割裂的,foo是怎么回到main函数中继续执行的呢?我们对上述代码进行反汇编。在main函数中,我们没有看到任何蛛丝马迹,只看到call指令。上图显示,当前代码执行到+8处(但是此行并没有执行,它的上一行执行了)。

方亮的专栏 1771
上一篇: 软件调试笔记29 - 运行库和运行期检查
下一篇: 内存分配函数
imJaron
博客等级 码龄11年 121粉丝 286原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值