为什么 AddressSanitizer 将野指针报告为堆缓冲区溢出而不是释放后使用
Why AddressSanitizer report wild pointer as a heap-buffer-overflow instead of use-after-free
class ISettingChangedListener
{
public:
virtual void NotifySettingsChanged() = 0;
};
class View : public ISettingChangedListener {
// ...
}
// Set the listener as a pointer to a view
void System::SetListener(ISettingChangedListener *listener) {
m_settings_changed_listener = listener;
}
// view is destroyed somewhere by delete
// after a while when the settings is about to change
void System::ChangeSettings() {
// do some modify
m_settings_changed_listener->NotifySettingsChanged(); // report a heap-over-flow instead of use-after-free
}
代码流程如上注释。是因为释放的内存被其他代码或其他东西重新分配了吗?
当删除 View object
后立即调用 NotifySettingsChanged
时,另一个测试代码导致 use-after-free
。
是 use-after-free
只能检测到相对较新的释放(只要它们适合隔离内存)。您可以通过在 ASAN_OPTIONS=quarantine_size_mb=512
中设置更高的值来提高可检测性(x86 上的默认值为 256,Android/iOS 上的默认值为 16),但这不能解决根本原因。
在您的特定情况下,内存可能重新分配了较小的大小,因此 Asan 认为您有堆溢出。
class ISettingChangedListener
{
public:
virtual void NotifySettingsChanged() = 0;
};
class View : public ISettingChangedListener {
// ...
}
// Set the listener as a pointer to a view
void System::SetListener(ISettingChangedListener *listener) {
m_settings_changed_listener = listener;
}
// view is destroyed somewhere by delete
// after a while when the settings is about to change
void System::ChangeSettings() {
// do some modify
m_settings_changed_listener->NotifySettingsChanged(); // report a heap-over-flow instead of use-after-free
}
代码流程如上注释。是因为释放的内存被其他代码或其他东西重新分配了吗?
当删除 View object
后立即调用 NotifySettingsChanged
时,另一个测试代码导致 use-after-free
。
是 use-after-free
只能检测到相对较新的释放(只要它们适合隔离内存)。您可以通过在 ASAN_OPTIONS=quarantine_size_mb=512
中设置更高的值来提高可检测性(x86 上的默认值为 256,Android/iOS 上的默认值为 16),但这不能解决根本原因。
在您的特定情况下,内存可能重新分配了较小的大小,因此 Asan 认为您有堆溢出。