GCC8.1/8.2下C++14启用-fsanitize=undefined时invalid vptr问题求解
问题解决:多重虚拟继承类删除触发invalid vptr错误(GCC 8.1/8.2 + UBSan)
问题本质
这是GCC 8.1/8.2版本的已知UBSan(未定义行为 sanitizer)专属bug,针对多重虚拟继承对象销毁时的vptr(虚指针)处理逻辑存在缺陷,导致UBSan误报(或触发真实未定义行为)。仅当同时启用-fsanitize=undefined和-fno-sanitize-recover=undefined时错误会终止程序,其他编译环境下程序可正常执行。
可行修复方案
- 升级GCC版本:该bug在GCC 8.3及后续版本中已被修复,升级到GCC 8.3或更高版本(如GCC 9/10/11),即可保留UBSan编译选项的同时正常运行代码。
- 调整销毁时的指针类型:若无法升级编译器,销毁对象时将指针强制转换为最顶层的基类类型再执行delete,绕过GCC 8.x的vptr异常处理逻辑:
// 假设类结构为:TopBase <- VirtualBase <- Derived(多重虚拟继承) Derived* ptr = new Derived(); delete static_cast<TopBase*>(ptr); - 临时禁用局部UBSan检测:作为应急方案,可在delete语句所在代码块临时关闭UBSan检测(注意会跳过该块所有未定义行为检查):
Derived* ptr = new Derived(); #pragma GCC diagnostic push __attribute__((no_sanitize("undefined"))) { delete ptr; } #pragma GCC diagnostic pop
结论
该场景并非代码逻辑错误,而是编译器版本的专属bug,通过上述方案可解决问题,并非无法运行。
内容的提问来源于stack exchange,提问作者Oshio
相关产品推荐
相关产品推荐

