当前位置: 首页 > wzjs >正文

农村电商网站建设方案郑州关键词优化费用

农村电商网站建设方案,郑州关键词优化费用,郑州汉狮做网站费用,免费b2b网站做推广注:栈回溯无法很好的定位到未调优化的函数,需要编译前使用 -fno-optimize-sibling-calls 选项禁止尾调优化。 基于unwind的栈回溯 在 arm 架构下,不少32位系统用的是 unwind 形式的栈回溯,这种栈回溯要复杂很多。首先需要程序有一…

注:栈回溯无法很好的定位到未调优化的函数,需要编译前使用 -fno-optimize-sibling-calls 选项禁止尾调优化。

基于unwind的栈回溯

  在 arm 架构下,不少32位系统用的是 unwind 形式的栈回溯,这种栈回溯要复杂很多。首先需要程序有一个特殊的段 .ARM.unwind_idx 或者.ARM.unwind_tab,在连接文件中增加 __start_unwind_idx,这就是 ARM.unwind_idx 段的起始地址。这个unwind段中存储着跟函数入栈相关的关键数据。当函数执行入栈指令后,在 unwind 段会保存跟入栈指令一一对应的编码数据,根据这些编码数据,就能计算出当前函数栈大小和 cpu 的哪些寄存器入栈了,已经在栈中什么位置。
  当栈回溯时,首先根据当前函数中的指令地址,就可以计算出函数 unwind 段的地址,然后从 unwind 段取出跟入栈有关的编码数据,根据这些编码数据就能计算出当前函数栈的大小以及入栈时 lr 寄存器数据在栈中的存储地址。这样就可以找到 lr 寄存器数据,就是当前函数返回地址,也就是上一级函数的指令地址。此时sp一般指向的函数栈顶,SP+函数栈大小 就是上一级函数的栈顶。这样就完成了一次栈回溯,并且知道了上一级函数的指令地址和栈顶地址,按照同样的方法就能对上一级函数栈回溯,类推就能实现整个栈回溯流程。
  编译时需要加入 -funwind-tables 选项,此选项在编译时会依赖 标准glibc 库,要求不能使用 -nostdlib 选项,否则会报某些函数缺失错误。

.ARM.exidx : {__exidx_start = .;*(.ARM.exidx* .gnu.linkonce.armexidx.*)__exidx_end = .;}

优缺点分析

  • 缺点
    需要在代码的连接脚本中增加新的 unwind 专用段,对资源要求较高,且修改连接脚本容易引发未知问题。

  • 优点
    暂未详细分析。

基于FP寄存器的栈回溯

  APCS 规范在ARM架构上定义了程序函数调用和栈帧定义以及寄存器的使用的规范,中定义了 FP 和 IP 寄存器的作用,目前这个规范已经被 AAPCS 规范所取代,此种方式基本已经不在使用。
在这里插入图片描述

核心思想

  通过当前获取异常时的 FP 寄存器,找到调用者的栈帧开始地址,再通过栈帧下的相对偏移找到调用栈下的LR,从而确定子函数跳转地址 PC = LR - 跳转指令大小。

回溯过程

  1. 异常处理函数中获取线程异常时的堆栈指针 SP(获取MSP) 和 FP;

  2. 通过FP寄存器找到当前栈的栈帧开始位置,并通过偏移和LR的指令特征找到 fun_B 栈帧下存放的 LR

  3. 通过 (PC = *LR-跳转指令大小) 确定父函数 fun_A 调用异常函数 fun_B 的地址

  4. 通过获取 PC 地址下的指令,通过BL/BLX解码 找到 fun_B 函数的地址

  5. 通过相对偏移找到函数 fun_B 栈帧下的FP,从而找到函数 fun_A 的栈帧开始地址,执行LR搜索和指令解码

  6. 最后会找到 main 函数栈帧的开始地址,通过main栈帧偏移找到LR地址,发现 *LR 的地址是线程 main 函数退出收尾函数时停止栈回溯。

优缺点分析

  • 优点
  1. 实现方案简单,栈回溯效率高,能够直接确定调用者的栈帧开始地址,快速定位到调用者栈帧下的 LR;

  2. 栈的遍历中无需检查每个 LR 的特征,通用语Thumb 和 ARM 指令集;

  • 缺点
  1. 目前基本不在使用APCS规范,高于gcc 5.0 版本的编译器不在支持 FP寄存器的压栈;

  2. 需要修改链接脚本,在编译选项中加入-fomit-frame-pointer -mapcs-frame;

  3. 在每个函数下都增加了 FP 等寄存器的压栈指令,调试时与实际运行程序有差别;

基于SP遍历 LR 的栈回溯

在这里插入图片描述

核心思想

  获取异常发生时线程函数的 SP(MSP),然后逐个从栈上取出内容进行判断,在 Thumb 指令集下栈上保存的 LR 是父函数进入子函数位置的下一条指令位置 +1,这里的+1表明了栈上 LR 位置存放的一定是一个奇数,再判断这个奇数-1 是否在 .text 段范围内,筛选出奇数后判断 *LR - 4 和 *LR - 2 位置是否满足 BL/BLX 指令特征,对于 ARM 指令集下栈上保存的 LR 是父函数进入子函数位置的下一条指令位置,这个值是4字节对齐的,再判断这个奇数-1 是否在 .text 段范围内,筛选出 4 字节对齐的内容后判断 *LR - 4 和 *LR - 2 位置是否满足 BL/BLX 指令特征,然后计算出跳转指令大小 PC=(*LR-指令大小) 就是 子函数调用位置,再根据获取 PC 下的指令,对指令进行地址解码就可以找到函数开始地址了。

回溯过程

  1. 异常处理函数中获取线程异常时的堆栈指针 SP(获取MSP),中断/内核栈下的PC(指向异常发生时的执行指令);
  2. 从异常时 SP 向上遍历栈帧找到 Thumb 指令集下 LR1 位置下的内容为 0x60256b93 这是一个奇数,然后取出 0x60256b93 - 1 - 4 = 0x60256b8e ,判断这个地址是否在 .text 段范围内,再判断指令是否为 bl/blx中的一种,如果是则说明找到了父函数 fun_A 调用 fun_B 的位置,记录下来;
  3. 继续向上遍历栈,找到 Thumb 指令集下 LR2 位置下的内容为 0x602561e9 这是一个奇数,取出0x602561e9 - 1 -4 = 0x602561e4 地址下的内容,判断是否是 b/bl/blx中的一种,如果是则说明找到了父函数 main 调用fun_A 的位置,记录下来;
  4. 继续向上遍历栈,找到 Thumb 指令集下 LR3 位置,*LR3-1-4 等于线程退出收尾函数时停止栈回溯;

优缺点分析

  • 优点
  1. 栈回溯效率相对较高,只需遍历栈找特征LR值即可;
  2. 无需修改连接脚本,对原始SDK侵入性较小;
  • 缺点
  1. 严重依赖 LR 特征值,可能出现错误解析;
  2. 不同架构,以及Thumb 和 ARM 指令集中BL/BLX 指令格式不同,兼容较为繁琐;

基于SP 代码遍历的栈回溯

在这里插入图片描述

核心思想

  获取异常发生时线程函数的SP 和 PC ,通过 PC 位置在 .text 上寻找函数压栈操作指令 push/stmdb 和栈内存申请指令 sub/sub.w (SUB SP minus immediate) ,计算出栈帧大小,然后确定 LR 位置,确定调用者栈底位置 SP+framesize,然后在确定调用者调用子函数的位置 PC = LR - 跳转指令大小,之后根据 PC 位置继续从调用者函数的 .text 代码段遍历栈帧操作指令。

回溯过程

  1. 异常中断中获取线程异常时的堆栈指针 SP(获取MSP),中断/内核栈下的PC(指向异常发生时的执行指令);
  2. 向上遍历异常函数 fun_B 的 .text 段内容寻找 push 指令,解析 6026d17a 处压栈的寄存器个数4个寄存器包括 lr 寄存器,以此处 push 指令特征值为 0xb500,继续遍历 6026d178 处压栈寄存器个数为 4,则相对于 lr 寄存器的偏移 offsetsize = 4,此时栈帧大小为 8;
  3. 从 push 指令向下搜索栈扩展指令 sub/sub.w,6026d180 处在栈上申请了 386 *4 个空间;所以栈帧总大小为 framesize = 386+8;
  4. 确定 LR 位置 LR = SP + framesize - offsetsize;
  5. 确定调用者 fun_A 函数栈帧(调用者栈)的栈帧底部位置 SP = SP + framesize;
  6. 再通过 (*LR - 跳转指令大小) = PC 确定 fun_A 中调用 fun_B 的位置;
  7. 之后继续从 fun_A 下的 .text 段的 PC 位置向上遍历,如此循环,直到找到的 *LR 是线程退出收尾函数为止;

优缺点分析

  • 优点
  1. 对栈上内容的依赖性较小,完全通过 .text 代码节进行遍历;
  2. 栈的遍历中无需检查每个 LR 的特征,适用于 Thumb 和 RAM 指令集;
  • 缺点
  1. 效率较低,需要对从函数开始到子函数跳转位置进行遍历,如果函数很长则影响效率;
  2. 复杂性高,需要解析栈操作指令来获取压栈和栈扩展的大小,从而确定栈帧大小;

内存泄露定位

打印栈帧还有一个应用,就是检查谁引起内存泄露:

// s_array 为全局数组
static int alloc_en(void *addr, unsigned int size);void* malloc_wrapper(unsigned int size)
{void *ptr = (void*)malloc(size);alloc_en(ptr, size);return ptr;
}static int alloc_en(void *addr, unsigned int size)
{for(i = 0; i < MAX_CALL; ++i){if(NULL == s_array[i].addr)break;}if(i >= MAX_CALL){printf("no free slot");return -1;}s_array[i].addr = (U32)addr;s_array[i].size = size;s_array[i].caller = backtrace(3);// 三级调用者是谁?
}

🌀路西法 的个人博客拥有更多美文等你来读。

http://www.dtcms.com/wzjs/80655.html

相关文章:

  • 贵州城乡和建设厅网站怎么样进行网络推广
  • 自己做网站语言构建服务器网推平台
  • 江苏专业做网站南京今天重大新闻事件
  • 做一款小说网站滕州百度推广
  • 邹平市建设局官方网站银川网站seo
  • 网络规划设计师企业数据中心机房建设网站seo方案模板
  • 网站流量如何突破南京疫情最新情况
  • 国内建站 wordpressseo指的是搜索引擎
  • 景德镇建设网站软文营销常用的方式是什么
  • 大学培训中心网站建设登封网络推广
  • 大连建设厅网站seop
  • 移动端网站开发标题设置seo软件服务
  • wordpress悬浮导航代码郑州技术支持seo
  • 怎么做网站导航高级seo是什么职位
  • 百度网站的结构网站快速收录的方法
  • 网站建设推广培训网页设计模板素材图片
  • 深圳网站建设网站交换免费连接
  • 福田网站建设seo新科百度快速收录办法
  • 群晖nas怎样做网站刷神马seo排名首页排名
  • 网站建设方案-奢侈品宁德市委书记
  • 潍坊建设局官方网站中国关键词官网
  • 网站建设 我们是专业的百度小说风云榜总榜
  • 武汉 网站制作简述获得友情链接的途径
  • wordpress熊掌号文章提交海淀区seo多少钱
  • 松岗做网站公司百度关键词排行榜
  • 同ip网站是怎么做的跨境电商平台排行榜前十名
  • 做代理需要自己的网站吗新的数据新闻
  • 临湘网站建设应用宝aso优化
  • 上海云站网络技术服务中心seo技术员
  • 单页网站制作网站做seo教程