English 中文(简体)
GCC的异常处理模型
原标题:
  • 时间:2008-11-25 18:22:15
  •  标签:

GCC支持Setjump-longjump (sjlj)和Dwarf2基于表的解旋(d2)异常处理模型。这两种模型的区别在哪里,如何选择适当的模型?为什么Dwarf2基于表的解旋(d2)是更高效的模型?我了解到这两种模型不能混合使用。

参考:技术预览:gcc-4.2.1-sjlj-2

最佳回答

嗯,dwarf2会为每个函数建立表,其中包含被调用者保存的寄存器以及它们在堆栈中的保存位置,以及调用栈中的帧指针/返回地址,以及其他一些内容。如果使用dwarf2,编译器可以使用这些信息有效地恢复寄存器,并在异常事件中跳回到调用者。后端需要在其实现的前导代码中提供信息,告诉GCC哪些寄存器是被调用者保存的,以及何时保存帧指针等等。

使用setjmp / longjmp只是一个hack。由于setjmp / longjmp不知道抛出函数的结构,它将恢复由setjmp保存在跳转缓冲区中的所有寄存器,即使它们没有被抛出函数覆盖。我并不是真正的专家,但我认为这很明显不是有效的。此外,每次启动try块时,都必须调用setjmp来设置包含保存的寄存器的缓冲区,在使用dwarf2时,编译器已在编译时提供了所有必要的信息。

如果后端无法提供必要的信息,GCC将自动回退到基于setjmp/longjmp的异常处理。

请注意,我不是GCC专家。我只是将工具链移植到我教授的一些简单处理器上,其中包括GCC。希望我能对您有所帮助。

问题回答

Avoid sjlj. Every "try" block will call setjmp which saves registers, a performance hit even when no exceptions are raised. Using tables, the normal flow of control incurs no execution cost. Only when an exception is raised does the exception handling mechanism have to grovel through the tables to figure out what to do.





相关问题
热门标签