地址清理器在静态强制转换无效指针时报告错误
address sanitizer reports error when statically casting an invalid pointer
当将未分配内存中的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 在此处报告无效的读取访问权限?难道不应该在编译时知道指针偏移量以及因此正确的结果指针值吗?
那么,为什么这种读取访问权限甚至是必要的呢?
指针偏移,因此不应正确生成指针 在编译时知道值?
不,虚拟继承类的偏移量在编译时是未知的,因此编译器在运行时通过访问 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++ PTHREADS - 无效转换无效*(*)()到无效*(*)(无效*)
- is_same和variadic模板编译时错误无效转换
- 如何将常量无效*转换为istream?
- 无效* 转换获得意外输出
- 无法确定为什么函数调用中从 char* 到 char 的无效转换
- 在这个简单函数中从'char'到'const char*'的无效转换
- C++从 'const char*' 到 'char*' Arduino Uno 的无效转换
- 如何修复C++中的"错误:从'int'到'const char*'[-fallowive]的无效转换?
- C 错误:从(基类模板)到子类的无效转换
- 如何将常量无效*转换为无符号字符*
- 函数模板中的无效转换错误,返回值取决于其泛型类型
- 常量正确性编译错误到模板函数中的无效转换错误
- 从"char"到"const char*"的无效转换[-fpermissive](idk why)
- 从“ void*”到“ pthread_t*”的无效转换
- 当函数调用时,试图阻止数组更改时发生无效转换错误
- 使用基类中定义的函数返回指向派生类实例的指针时发生无效转换错误
- C++从字符到常量字符*的无效转换
- ALL_OF从'char'到'const char*'的无效转换 [-允许]
- C和C++上的无效转换错误
- C++ 在模板专用化中从 strcmp() 中的 'char' 到 'const char*' 的无效转换