更新:我创造了更多M,但仍然是CVE再现崩溃.摘要:删除了类中所有Bool* bools_字段的使用Base(但仍然必须定义或不发生崩溃).还删除Base::Initialize()了Rule来自Base及其后代的虚方法.附加了新的MCVE.
我已经设法为此代码创建了一个MCVE并在下面发布了它.
一些描述性细节:代码使用虚拟基类和派生类,并且实例化的某些派生类具有构造函数,这些构造函数调用从"基础"类继承的非虚方法(实际上是派生类,但在继承层次结构中高于我称之为"派生"类来初始化"基础"类数据.该方法调用在派生类中重写的虚方法.我意识到这是一件危险的事情,但是从我(可能是有限的)对C++的理解来看,它似乎应该有效,因为派生类构造函数的主体在设置"基"类虚拟表之前不会执行.在任何情况下,在调用"base"类的初始化方法期间不会发生段错误.
段错误发生在"base"类构造函数中,并且仅在构造函数的主体为空时发生.如果我向构造函数添加一个调试行,以便在到达该点时打印出来,则打印出调试行并且代码正常运行.我的猜测是,由于某种原因,编译器正在优化在"base"类的构造函数的主体执行之前应该发生的初始化,包括设置vtable.
正如主题所说,这个代码在没有使用Apple的g ++或g ++ 7.2.0进行优化编译时运行良好,并且在使用g ++ 7.2.0编译甚至-O3时运行正常.它只在编译时-O2或-O3使用Apple的LLVM实现g ++时出现段错误.该g++ --version编译器的输出是:
% /usr/bin/g++ --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.39.2)
Target: x86_64-apple-darwin17.3.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Content
Run Code Online (Sandbox Code Playgroud)
MCVE如下.
#include <iostream>
using namespace std;
class OriginalBaseClass {
public:
OriginalBaseClass(long double data1 = 1, long int data2 = 1) : data1_(data1), data2_(data2) { cout << "In OriginalBaseClass constructor\n"; }
private:
long …Run Code Online (Sandbox Code Playgroud)