c++ - 地址 sanitizer 在静态转换无效指针时报告错误

标签 c++ c++11 gcc address-sanitizer

当将未分配内存中的 Derived* 静态转换为 Base* 时,gcc 的 ASAN 报告:

ASAN:DEADLYSIGNAL
=================================================================
==12829==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x563da3783776 bp 0x7ffde1670e50 sp 0x7ffde166d800 T0)
==12829==The signal is caused by a READ memory access.
==12829==Hint: address points to the zero page.

为了测试,我使用了这个设置:

struct Base2 { int dummy; };
struct Base { int dummy2; };
struct Derived : public Base2, public virtual Base { };

Derived* derived = (Derived*)0x1122334455667788; /* some pointer into non-allocated memory */
Base* base = static_cast<Base*>(derived); /* ASAN fails here */

为什么 ASAN 在这里报告无效的读取访问?指针偏移量和正确的结果指针值不应该在编译时已知吗?

那么为什么这种读取权限是必需的?

最佳答案

Shouldn't the pointer offset and therefore the correct resulting pointer value be known at compile time?

不,虚拟继承类的偏移量在编译时是未知的,因此编译器会在运行时通过访问 vtable 来计算它。

这是一个简单的例子:

Base *foo(Derived *p) {
  return static_cast<Base*>(p);
}

编译为

movq    (%rdi), %rax     # Get vptr
addq    -24(%rax), %rdi  # Load offset of Base from vtable
movq    %rdi, %rax       # Return result
ret

ASan 提示是因为您尝试访问一些导致段错误的随机内存地址。

关于c++ - 地址 sanitizer 在静态转换无效指针时报告错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48623408/

相关文章:

c++ - 是否有用于右值引用的 reference_wrapper<>?

c++11 - 为什么 'scientific' 改变了 'precision' 的含义?

c++ - 线程(C++ 中的并行计算)是否与优化级别 (gcc) 不兼容?

ubuntu - 在 ubuntu 17.04 上从源代码构建 llvm 3.42 失败

python - 在 Ubuntu 12.04 中安装 psycopg2 时出错

c++ - wxTextValidator 导致崩溃

c++ - OpenGL - 在 ubuntu 中的线程上创建 vbo?

c++ - 来自 EPEL 的 Amazon Linux 上的 Clang 无法找到 C++ header 或库

c++ - this* 在 make_unique 中的用法

c++ - 在 C++ 中使用重载 + 添加 2 个 vector