gpt4 book ai didi

c++ - 到达展开处理程序

转载 作者:行者123 更新时间:2023-11-30 02:21:30 25 4
gpt4 key购买 nike

知道为什么代码看起来像这样

list<Foo> fooList;
processList(&fooList);

生成如下机器码

    lea     rax, [rbp-48]
mov rdi, rax
call processList(std::__cxx11::list<Foo, std::allocator<Foo> >*)
lea rax, [rbp-48]
mov rdi, rax
call std::__cxx11::list<Foo, std::allocator<Foo> >::~list()
jmp .L11
mov rbx, rax
lea rax, [rbp-48]
mov rdi, rax
call std::__cxx11::list<Foo, std::allocator<Foo> >::~list()
mov rax, rbx
mov rdi, rax
call _Unwind_Resume
.L11:
add rsp, 40
pop rbx
pop rbp
ret

特别是,我没有看到任何通往无条件 jmp .L11

之后的行的路径

(这是 GCC 6.2 没有优化,在编译器资源管理器上生成)

为了对比,clang 5.0.0产生

    call    processList(std::__cxx11::list<Foo, std::allocator<Foo> >*)
jmp .LBB5_1
.LBB5_1:
lea rdi, [rbp - 24]
call std::__cxx11::list<Foo, std::allocator<Foo> >::~list()
add rsp, 48
pop rbp
ret
lea rdi, [rbp - 24]
mov ecx, edx
mov qword ptr [rbp - 32], rax
mov dword ptr [rbp - 36], ecx
call std::__cxx11::list<Foo, std::allocator<Foo> >::~list()
mov rdi, qword ptr [rbp - 32]
call _Unwind_Resume

再次出现无条件跳转到返回 block 和展开 block (从第二个 lea rdi 开始)似乎无法访问。

最佳答案

经过对C++异常机制的一些研究,我的结论是流程如下:

  1. 在异常抛出点,__cxa_throw 被调用。这有点像 longjmp(),因为该函数被调用但从不返回。该函数执行两个主要任务
    • 它遍历调用堆栈以寻找捕获点。如果未找到任何内容,则调用 std::terminate
    • 如果它确实找到了一个 catch block ,那么它会调用当前函数和 catch block 之间的所有展开处理程序,然后调用 catch block 。

回到我原来的机器代码(在编译器资源管理器中关闭过滤)。我在哈希后的评论。

    # this is the normative path
call std::list<Handle, std::allocator<Handle> >::~list()
# unconditional jump around the unwind handler
jmp .L11
.L10:
# unwind handler code, calls the local variable destructor
mov rbx, rax
.loc 2 30 0
lea rax, [rbp-32]
mov rdi, rax
call std::list<Handle, std::allocator<Foo> >::~list()
mov rax, rbx
mov rdi, rax
.LEHB1:
# carry on unwinding
call _Unwind_Resume

.L11:

然后是异常表

   .section        .gcc_except_table,"a",@progbits
.LLSDA1386:
.byte 0xff
.byte 0xff
.byte 0x1
.uleb128 .LLSDACSE1386-.LLSDACSB1386
.LLSDACSB1386:
# entry for unwind handler
.uleb128 .LEHB0-.LFB1386
.uleb128 .LEHE0-.LEHB0
.uleb128 .L10-.LFB1386
.uleb128 0
.uleb128 .LEHB1-.LFB1386
.uleb128 .LEHE1-.LEHB1
.uleb128 0
.uleb128 0

我猜 unwind handler 函数可以根据堆栈上的地址和此表中的偏移量计算出 unwind handler block 的位置。

关于c++ - 到达展开处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48248997/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com