内容简介:上次我们了解到,就像throw语句被翻译为一对__cxa_allocate_exception/throw调用,catch块被翻译为一对__cxa_begin/end_catch调用,加上称为CFI(调用帧信息)的对象,来查找着陆垫——函数处理异常之处。我们尚不知道的是_Unwind_如何知道着陆垫在哪里。在一个异常被抛出时,栈上有一组函数;所有CFI内容将让Unwind知道这些是什么函数,但知道每个函数提供哪些着陆垫也是必须的,因此我们可以调用每个函数,核查它是否希望处理这个异常(我们忽略带有多个try/
作者: nicolasbrailo
上次我们了解到,就像throw语句被翻译为一对__cxa_allocate_exception/throw调用,catch块被翻译为一对__cxa_begin/end_catch调用,加上称为CFI(调用帧信息)的对象,来查找着陆垫——函数处理异常之处。
我们尚不知道的是_Unwind_如何知道着陆垫在哪里。在一个异常被抛出时,栈上有一组函数;所有CFI内容将让Unwind知道这些是什么函数,但知道每个函数提供哪些着陆垫也是必须的,因此我们可以调用每个函数,核查它是否希望处理这个异常(我们忽略带有多个try/catch块的函数)。
要知道着陆垫在哪里,要使用称为gcc_except_table的东西。在函数末尾可以找到这(带有一组CFI):
|
|
节.gcc_except_table是所有定位着陆垫信息保存的地方,一旦我们设法分析了personality函数后,我们再来更多地了解它;目前,我们只是说LSDA表示语言特定数据区域,它是personality函数检查对一个函数是否存在任何着陆垫的地方(在回滚栈时,它也用于运行析构函数)。
总之:对每个至少找到一个catch的函数,编译器将把这个语句翻译为一对__cxa_begin_catch/ __cxa_end_catch调用,接着personality函数,被__cxa_throw调用,将为栈上每个函数读gcc_except_table,查找称为LSDA的东西。然后Personality函数将在LSDA里检查一个catch是否能处理一个异常,是否有清理代码运行(这就是在需要时触发析构函数的原因)。
这里我们还可以得到一个有趣的结论:如果我们使用nothrow说明符(或者空的throw指示符),编译器可以为这个方法忽略gcc_except_table。Gcc实现异常的方式,不会对性能产生大的影响,但确实将减小代码大小。Catch是什么?如果在指明nothrow时抛出一个异常,不存在LSDA,personality函数不知道怎么做。在personality函数不知道做什么时,它将调用缺省的异常处理句柄,意味着在大多数情形里从一个nothrow方法抛出将最终调用std::terminate。
现在我们了解了personality函数是什么,我们可以实现它吗?下一节我们来看如何做。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Python 拓展之特殊函数(lambda 函数,map 函数,filter 函数,reduce 函数)
- Python 函数调用&定义函数&函数参数
- python基础教程:函数,函数,函数,重要的事说三遍
- C++函数中那些不可以被声明为虚函数的函数
- 017.Python函数匿名函数
- 纯函数:函数式编程入门
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
API Design for C++
Martin Reddy / Morgan Kaufmann / 2011-2-18 / USD 59.95
The design of application programming interfaces can affect the behavior, capabilities, stability, and ease of use of end-user applications. With this book, you will learn how to design a good API for......一起来看看 《API Design for C++》 这本书的介绍吧!