AddressSanitizer在合法C++代码中偶现内存错误,是否为编译器问题?
问题描述
以下是相关C++代码:
#include <iostream> #include <set> #include <iterator> using std::cout, std::endl; using std::multiset; int main() { multiset<int> m; m.insert(1); m.insert(2); m.insert(3); m.erase(std::prev(m.end())); for (auto &i : m) { cout << i << ' '; } cout << endl; }
使用g++ -o main main.cpp编译时,代码运行正常;但使用g++ -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -fstack-protector -o main main.cpp编译后,约每10次运行中会出现1次AddressSanitizer:DEADLYSIGNAL报错。
当前使用编译器版本:g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 Copyright (C) 2021 Free Software Foundation, Inc.
请问此情况是否属于编译器错误?
分析与结论
这段代码完全符合C++标准:std::prev(m.end())获取的是multiset最后一个元素的合法迭代器,multiset::erase接受该迭代器的操作是合规的,不存在未定义行为。
出现低概率的AddressSanitizer报错,大概率是GCC 11.4版本中AddressSanitizer组件的实现bug,或是sanitizer与标准库libstdc++的交互问题。因为标准代码在普通编译模式下稳定运行,仅在开启特定sanitizer选项时偶现崩溃,且触发概率低,符合工具链实现层面偶发bug的特征。
建议尝试升级GCC版本至12.x及以上,新版本通常会修复这类sanitizer相关的已知问题。
内容的提问来源于stack exchange,提问作者Couchcap
相关产品推荐
相关产品推荐

