【发布时间】:2018-01-14 11:15:48
【问题描述】:
知道为什么代码看起来像这样
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
再次无条件跳转到返回块和似乎无法到达的展开块(从第二个 lea rdi 开始)。
【问题讨论】:
-
您是否尝试过在启用优化的情况下进行编译?
-
异常处理程序不应该通常可以访问,这就是重点
-
好吧,让我改写一下:异常处理程序无法通过正常的控制流访问。您只查看正常的控制流,因此它们无法访问。
-
通过展开过程,所以看一下.eh_frame之类的
-
@PaulFloyd 如果您在没有优化的情况下进行编译,那么在二进制文件中看到死(无法访问)代码并不少见。毕竟,您通过关闭优化器来禁止编译删除此类代码。
标签: c++ assembly x86-64 stack-unwinding