转储 C++ 对象的内存布局在 clang 中不起作用

Igo*_*gor 4 c++ macos llvm clang

我读过一篇关于使用 Clang 转储 C++ 对象的内存布局的文章,现在我正在尝试使用此功能。我创建了两个类:

// simple.cpp
struct Base
{
    int value;
};

struct Derived : Base
{
    int count;
};

int main(int argc, char* argv[])
{
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

并运行以下命令:

$ clang -cc1 -fdump-record-layouts-simple simple.cpp
Run Code Online (Sandbox Code Playgroud)

却一无所获。铿锵版本是:

$ clang++ -dumpversion
4.2.1
Run Code Online (Sandbox Code Playgroud)

如果我运行以下命令:

$ clang -cc1 --help
Run Code Online (Sandbox Code Playgroud)

在很多信息中我可以找到这个:

...
  -fdump-record-layouts-simple
                          Dump record layout information in a simple form used for testing
  -fdump-record-layouts   Dump record layout information
  -fdump-vtable-layouts   Dump the layouts of all vtables that will be emitted in a translation unit
...
Run Code Online (Sandbox Code Playgroud)

我做错了什么?

Joh*_*nck 5

您需要进行两项更改:

  1. 添加-emit-llvm编译器开关。如果没有这个,就不需要 LLVM 输出,因此永远不会计算记录布局,因此也不会转储。
  2. 使用代码中的类。如果从未使用过这些类,则不会为它们生成代码,并且不会转储它们的布局。

进行这些更改后,类似这样的输出将打印在标准输出上:

*** Dumping AST Record Layout
Type: struct Base

Layout: <ASTRecordLayout
  Size:32
  DataSize:32
  Alignment:32
  FieldOffsets: [0]>

*** Dumping AST Record Layout
Type: struct Derived

Layout: <ASTRecordLayout
  Size:64
  DataSize:64
  Alignment:32
  FieldOffsets: [32]>
Run Code Online (Sandbox Code Playgroud)

...

Layout: <CGRecordLayout
  LLVMType:%struct.Base = type { i32 }
  NonVirtualBaseLLVMType:%struct.Base = type { i32 }
  IsZeroInitializable:1
  BitFields:[
]>

Layout: <CGRecordLayout
  LLVMType:%struct.Derived = type { %struct.Base, i32 }
  NonVirtualBaseLLVMType:%struct.Derived = type { %struct.Base, i32 }
  IsZeroInitializable:1
  BitFields:[
]>
Run Code Online (Sandbox Code Playgroud)


Chr*_*vey 5

以下是根据我使用 clang 10.0.1 的经验进行的更新:

  • 一个必要条件是编译器需要一些理由来真正关心相关结构的布局。因此,simple.cpp原始问题中的源文件似乎永远不会导致转储。我发现添加代码来实例化其中一个结构,或者调用sizeof(...)它,或者调用它们的虚拟方法之一,是有效的。

  • 如果您使用-cc1,则需要-emit-llvm 或 来 -emit-obj引发转储。(也许其他选项也有效,但在我的实验中,我至少需要其中之一。)

  • 如果您不想使用该-cc1选项(可能是因为您只想将它​​们添加到假定 g++ 兼容性的现有构建系统中),则像这样的调用也可以工作:clang -Xclang -fdump-record-layouts-simple simple.cpp。(这种方法的一个好处是,至少在我的系统上,以这种方式调用 clang 会导致结构布局信息在我的终端中着色。)

  • 我上面写的东西似乎也适用于-fdump-record-layouts-fdump-vtable-layouts选项。