- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我想知道GCC是如何为C++程序实现异常处理的。我无法在 Web 上找到一篇易于理解和不言自明的文章(尽管有很多针对 Visual C++ 的此类文章)。我只知道 GCC 的实现称为 DWARF 异常处理。
我写了一个小的 C++ 程序并用命令将它翻译成汇编:
g++ main.cpp -S -masm=intel -fno-dwarf2-cfi-asm
这里给出了main.cpp 和main.s 文件。谁能逐行解释 main.s 文件的内容,尤其是 .gcc_except_table
和 .eh_frame
部分? (我的操作系统是 Ubuntu 13.04 32 位。)谢谢!
main.cpp:
void f()
{
throw 1;
}
int main()
{
int j;
try {
f();
} catch (int i) {
j = i;
}
return 0;
}
main.s:
.file "main.cpp"
.intel_syntax noprefix
.text
.globl _Z1fv
.type _Z1fv, @function
_Z1fv:
.LFB0:
push ebp
.LCFI0:
mov ebp, esp
.LCFI1:
sub esp, 24
mov DWORD PTR [esp], 4
call __cxa_allocate_exception
mov DWORD PTR [eax], 1
mov DWORD PTR [esp+8], 0
mov DWORD PTR [esp+4], OFFSET FLAT:_ZTIi
mov DWORD PTR [esp], eax
call __cxa_throw
.LFE0:
.size _Z1fv, .-_Z1fv
.globl main
.type main, @function
main:
.LFB1:
push ebp
.LCFI2:
mov ebp, esp
.LCFI3:
and esp, -16
sub esp, 32
.LEHB0:
call _Z1fv
.LEHE0:
.L7:
mov eax, 0
jmp .L9
.L8:
cmp edx, 1
je .L6
mov DWORD PTR [esp], eax
.LEHB1:
call _Unwind_Resume
.LEHE1:
.L6:
mov DWORD PTR [esp], eax
call __cxa_begin_catch
mov eax, DWORD PTR [eax]
mov DWORD PTR [esp+24], eax
mov eax, DWORD PTR [esp+24]
mov DWORD PTR [esp+28], eax
call __cxa_end_catch
jmp .L7
.L9:
leave
.LCFI4:
ret
.LFE1:
.globl __gxx_personality_v0
.section .gcc_except_table,"a",@progbits
.align 4
.LLSDA1:
.byte 0xff
.byte 0
.uleb128 .LLSDATT1-.LLSDATTD1
.LLSDATTD1:
.byte 0x1
.uleb128 .LLSDACSE1-.LLSDACSB1
.LLSDACSB1:
.uleb128 .LEHB0-.LFB1
.uleb128 .LEHE0-.LEHB0
.uleb128 .L8-.LFB1
.uleb128 0x1
.uleb128 .LEHB1-.LFB1
.uleb128 .LEHE1-.LEHB1
.uleb128 0
.uleb128 0
.LLSDACSE1:
.byte 0x1
.byte 0
.align 4
.long _ZTIi
.LLSDATT1:
.text
.size main, .-main
.section .eh_frame,"a",@progbits
.Lframe1:
.long .LECIE1-.LSCIE1
.LSCIE1:
.long 0
.byte 0x1
.string "zPL"
.uleb128 0x1
.sleb128 -4
.byte 0x8
.uleb128 0x6
.byte 0
.long __gxx_personality_v0
.byte 0
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.byte 0x88
.uleb128 0x1
.align 4
.LECIE1:
.LSFDE1:
.long .LEFDE1-.LASFDE1
.LASFDE1:
.long .LASFDE1-.Lframe1
.long .LFB0
.long .LFE0-.LFB0
.uleb128 0x4
.long 0
.byte 0x4
.long .LCFI0-.LFB0
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI1-.LCFI0
.byte 0xd
.uleb128 0x5
.align 4
.LEFDE1:
.LSFDE3:
.long .LEFDE3-.LASFDE3
.LASFDE3:
.long .LASFDE3-.Lframe1
.long .LFB1
.long .LFE1-.LFB1
.uleb128 0x4
.long .LLSDA1
.byte 0x4
.long .LCFI2-.LFB1
.byte 0xe
.uleb128 0x8
.byte 0x85
.uleb128 0x2
.byte 0x4
.long .LCFI3-.LCFI2
.byte 0xd
.uleb128 0x5
.byte 0x4
.long .LCFI4-.LCFI3
.byte 0xc5
.byte 0xc
.uleb128 0x4
.uleb128 0x4
.align 4
.LEFDE3:
.ident "GCC: (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3"
.section .note.GNU-stack,"",@progbits
最佳答案
Itanium ABI(gcc、clang 和其他一些都遵循)指定异常处理应遵循 Zero-Cost strategy .
零成本策略的想法是将所有异常处理推送到不保留在主程序执行路径上的副表中(因此不会破坏指令缓存)。这些表由程序点索引。
此外,DWARF 信息(实际上是调试信息)用于展开堆栈。此功能通常作为库提供,例如 libunwind例如,源代码充满了汇编(因此非常特定于平台)。
优点:
try
/catch
block 的成本为 0(就像没有 block 一样快)throw
语句的成本为 0(只要不采用)缺点:
if
策略慢 10 倍)因为副表通常不在缓存中,然后需要运行昂贵的计算才能知道哪个 catch
子句实际匹配(基于 RTTI)对于所有主要编译器,它是在 32 位和 64 位平台上非常流行的策略实现...除了 MSVC 32 位(如果我没记错的话)。
关于c++ - GCC C++ 异常处理实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18672191/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!