2014年4月7日星期一

c++ 异常处理(2) - twoon

本邮件内容由第三方提供,如果您不想继续收到该邮件,可 点此退订
c++ 异常处理(2) - twoon  阅读原文»

前面一篇博文简单介绍了c++异常处理的流程,但在一些细节上一带而过了,比如,_Unwind_RaiseException是怎样重建函数现场的,personality routine是怎样清理栈上变量的等,这些细节涉及到很多与语言层面无关的东西,本文尝试介绍一下这些细节的具体实现。

相关的数据结构

如前所述,unwind的进行需要编译器生成一定的数据来支持,这些数据保存了与每个可能抛异常的函数相关的信息以供运行时查找,那么,编译器都保存了哪些信息呢?根据Itanium ABI的定义,主要包括以下三类

1)unwind table,这个表记录了与函数相关的信息,共三个字段:函数的起始地址,函数的结束地址,一个info block指针。

2)unwind descriptor table, 这个列表用于描述函数中需要unwind的区域的相关信息。

3)语言相关的数据(language specific data area),用于上层语言内部的处理。

以上数据结构的描述来自Itanium ABI的标准定义,但在具体实现时,这些数据是怎么组织以及放到了哪里则是由编译器来决定的,对于GCC来说,所有与unwind相关的数据都放到了.eh_frame及.gcc_except_table这两个section里面了,而且它的格式与内容和标准的定义稍稍有些不同。

.eh_frame区域

.eh_frame的格式与.debug_frame是很相似的(不完全相同),属于DWARF标准中的一部分。所有由GCC编译生成的需要支持异常处理的程序都包含了DWARF格式的数据与字节码,这些数据与字节码的主要作用有两个:

1)描述函数调用栈的结构(layout)

2)异常发生后,指导unwinder怎么进行unwind。

DWARF的字节码功能很强大,它是图灵完备的,这意味着仅仅通过DWARF就可以做几乎任何事情。但是从数据的组织上来看,DWARF实在略显复杂晦杂,因此很少有人愿意去碰,本文也只是简单介绍其中与异常处理相关的东西。本质上来说,eh_frame像是一张表,它用于描述怎样根据程序中每一条指令来设置相应的寄存器,从而返回到当前函数的调用函数中去,它的作用可以用如下表格来形象地描述。

program counterCFAebp ebxeaxreturn address
0xfff0003001rsp+32*(cfa-16)*(cfa-24)eax=edi*(cfa-8) 
0xfff0003002rsp+32*(cfa-16) eax=edi*(cfa-8)
0xfff0003003rsp+32*(cfa-16)*(cfa-32)eax=edi*(cfa-8

上表中,CFA(canonical frame address的缩写)表示一个基地址,用于作为当前函数中的其它地址的起始地址,使得其它地址可以用与该基地址的偏移来表示,由于这个表可能要覆盖很多程序指令,因此这个表的体积有可能是很大的,甚至比程序本身的代码量还要大。而在实际中,为了减少这个表的体积,GCC通常会对它进行压缩编码,以及尽可能减少要覆盖的指令的数量,比如,只对会抛异常的函数里的特定区域指令进行记录。

具体的实现上,eh_frame由一个CIE (Common Information Entry) 及多个 FDE (Frame Description Entry)组成,它们在内存中是连续存放的:

CIE及FDE格式的定义可以参看如下:

CIE结构:

LengthRequired
Extended LengthOptional
CIE IDRequired
VersionRequired
Augmentation StringRequired
EH DataOptional
Code Alignment FactorRequired
Data Alignment FactorRequired
Return Address RegisterRequired
Augmentation Data LengthOptional
Augmentation DataOptional
Initial InstructionsRequired
Padding

FDE结构:

LengthRequired
Extended LengthOptional
CIE PointerRequired
PC BeginRequired
PC RangeRequired
Augmentation Data LengthOptional
Augmentation DataOptional
Call Frame InstructionsRequired
Padding职业规划那些事儿 - zhixing  阅读原文»

前几天写了招聘和面试方面的,也写了带新人方面的,今天我和朋友一起来探讨一下个人对于职业规划方面的理解,希望和朋友们一起分享
什么是职业规划呢,我想第一步首先要有以下三方面,另外的三方面下一篇文章会写出来,欢迎有不同意见的朋友指出。
1、目标
什么是目标呢,也就是我们想要做到什么事情或者做到什么职位,比如一个程序员需要做到的就是理解公司的技术框架和业务,一个项目经理就是带领项目组在某个时间段内完成一个项目,为什么要有目标呢,因为有了这个目标就有了前进的动力,也许我们技术还不完善,但是看到了同事的技术非常的精湛,经常找他来解决问题,也许他就是目标,通过自己的实践和努力有一天也可以帮助别人解决问题。也许有了很多年工作经验以后,就希望有一天做到项目经理的位置,那么自己身边的项目经理就是自己的目标,有一天也可以自己带领一个团队让项目在自己的管理之下成功上线。

其实目标对于一个程序员就相当于心灵的一盏明灯

2、计划
什么是计划呢,就是我们根据自身的情况在一定的时间内给自己的任务,比如我们进入一个公司,需要做的是熟悉公司的技术框架和业务,那么做到这些需要多久呢,毕竟在一个新的职位上,对于这些陌生的环境还有陌生的业务和技术,都是需要时间的,如果有了这个计划,就可以合理的检验自己的工作能力,也可以让自己的领导看到自己的进步,计划的时间可以根据自己的情况来定,比如刚刚毕业的大概需要一个月熟悉这些,但是对于一个3年以上工作经验的大概需要的是一周。还有对于一些跨行业的,比如之前是做企业管理开发的转到做金融项目,那么就是一个行业的转变了,可能需要的时间就会多一点,我刚刚有三年工作经验的时候,我的一个领导对我说的是进入一个新的行业至少需要三年,这点我是认同的,当然我们不排除有人会很快,我这个只是自己的一个比喻。

其实计划对于一个程序员就相当于需要多少步可以走到心灵的那盏明灯

3、信心
什么是信心呢,就是相信自己有能力面对眼前的困难,比如一个初级程序员面对的困难就是技术方面的,这些确实让人比较苦恼,因为技术是一点一点的积累的,但是有很多办法来解决的,比如问项目组的同事、通过百度搜索,或者查找相关的书籍,通过自身的努力解决之后,就会增加我们的信心,以后如果有其他同事遇到类似的困难,自己也可以帮助解决。如果是项目经理遇到的困难,比如人员的变化,需求的不稳定,如果有这些困难我们可以把困难升级,和项目组的同事一起协同面对困难,自己有了完成项目的信心,也会得到领导的支持,客户的认同。只有有不怕困难的信心,就可以距离目标越来越近。

其实信心对于一个程序员就相当于走向心灵的那盏明灯所具有的勇气。


以上的例子可能相对比较简单,遇到的不止这些,仅仅作为职业规划的参考


本文链接:职业规划那些事儿,转载请注明。

阅读更多内容

没有评论:

发表评论